xref: /third_party/libsnd/src/caf.c (revision b815c7f3)
1/*
2** Copyright (C) 2005-2017 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	<stdio.h>
22#include	<stdlib.h>
23#include	<string.h>
24#include	<ctype.h>
25#include	<math.h>
26#include	<inttypes.h>
27
28#include	"sndfile.h"
29#include	"sfendian.h"
30#include	"common.h"
31#include	"chanmap.h"
32
33/*------------------------------------------------------------------------------
34** Macros to handle big/little endian issues.
35*/
36
37#define aac_MARKER		MAKE_MARKER ('a', 'a', 'c', ' ')
38#define alac_MARKER		MAKE_MARKER ('a', 'l', 'a', 'c')
39#define alaw_MARKER		MAKE_MARKER ('a', 'l', 'a', 'w')
40#define caff_MARKER		MAKE_MARKER ('c', 'a', 'f', 'f')
41#define chan_MARKER		MAKE_MARKER ('c', 'h', 'a', 'n')
42#define data_MARKER		MAKE_MARKER ('d', 'a', 't', 'a')
43#define desc_MARKER		MAKE_MARKER ('d', 'e', 's', 'c')
44#define edct_MARKER		MAKE_MARKER ('e', 'd', 'c', 't')
45#define free_MARKER		MAKE_MARKER ('f', 'r', 'e', 'e')
46#define ima4_MARKER		MAKE_MARKER ('i', 'm', 'a', '4')
47#define info_MARKER		MAKE_MARKER ('i', 'n', 'f', 'o')
48#define inst_MARKER		MAKE_MARKER ('i', 'n', 's', 't')
49#define kuki_MARKER		MAKE_MARKER ('k', 'u', 'k', 'i')
50#define lpcm_MARKER		MAKE_MARKER ('l', 'p', 'c', 'm')
51#define mark_MARKER		MAKE_MARKER ('m', 'a', 'r', 'k')
52#define midi_MARKER		MAKE_MARKER ('m', 'i', 'd', 'i')
53#define mp1_MARKER		MAKE_MARKER ('.', 'm', 'p', '1')
54#define mp2_MARKER		MAKE_MARKER ('.', 'm', 'p', '2')
55#define mp3_MARKER		MAKE_MARKER ('.', 'm', 'p', '3')
56#define ovvw_MARKER		MAKE_MARKER ('o', 'v', 'v', 'w')
57#define pakt_MARKER		MAKE_MARKER ('p', 'a', 'k', 't')
58#define peak_MARKER		MAKE_MARKER ('p', 'e', 'a', 'k')
59#define regn_MARKER		MAKE_MARKER ('r', 'e', 'g', 'n')
60#define strg_MARKER		MAKE_MARKER ('s', 't', 'r', 'g')
61#define umid_MARKER		MAKE_MARKER ('u', 'm', 'i', 'd')
62#define uuid_MARKER		MAKE_MARKER ('u', 'u', 'i', 'd')
63#define ulaw_MARKER		MAKE_MARKER ('u', 'l', 'a', 'w')
64#define MAC3_MARKER		MAKE_MARKER ('M', 'A', 'C', '3')
65#define MAC6_MARKER		MAKE_MARKER ('M', 'A', 'C', '6')
66
67#define CAF_PEAK_CHUNK_SIZE(ch) 	((int) (sizeof (int) + ch * (sizeof (float) + 8)))
68
69/*------------------------------------------------------------------------------
70** Typedefs.
71*/
72
73typedef struct
74{	uint8_t		srate [8] ;
75	uint32_t	fmt_id ;
76	uint32_t	fmt_flags ;
77	uint32_t	pkt_bytes ;
78	uint32_t	frames_per_packet ;
79	uint32_t	channels_per_frame ;
80	uint32_t	bits_per_chan ;
81} DESC_CHUNK ;
82
83typedef struct
84{	int			chanmap_tag ;
85
86	ALAC_DECODER_INFO	alac ;
87} CAF_PRIVATE ;
88
89/*------------------------------------------------------------------------------
90** Private static functions.
91*/
92
93static int	caf_close (SF_PRIVATE *psf) ;
94static int	caf_read_header (SF_PRIVATE *psf) ;
95static int	caf_write_header (SF_PRIVATE *psf, int calc_length) ;
96static int	caf_write_tailer (SF_PRIVATE *psf) ;
97static int	caf_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
98static int	caf_read_chanmap (SF_PRIVATE * psf, sf_count_t chunk_size) ;
99static int	caf_read_strings (SF_PRIVATE * psf, sf_count_t chunk_size) ;
100static void	caf_write_strings (SF_PRIVATE * psf, int location) ;
101
102
103static int caf_set_chunk (SF_PRIVATE *psf, const SF_CHUNK_INFO * chunk_info) ;
104static SF_CHUNK_ITERATOR * caf_next_chunk_iterator (SF_PRIVATE *psf, SF_CHUNK_ITERATOR * iterator) ;
105static int caf_get_chunk_size (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) ;
106static int caf_get_chunk_data (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) ;
107
108/*------------------------------------------------------------------------------
109** Public function.
110*/
111
112int
113caf_open (SF_PRIVATE *psf)
114{	CAF_PRIVATE * pcaf ;
115	int	subformat, format, error = 0 ;
116
117	if ((psf->container_data = calloc (1, sizeof (CAF_PRIVATE))) == NULL)
118		return SFE_MALLOC_FAILED ;
119
120	pcaf = psf->container_data ;
121
122	if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
123	{	if ((error = caf_read_header (psf)))
124			return error ;
125
126		psf->next_chunk_iterator = caf_next_chunk_iterator ;
127		psf->get_chunk_size = caf_get_chunk_size ;
128		psf->get_chunk_data = caf_get_chunk_data ;
129		} ;
130
131	subformat = SF_CODEC (psf->sf.format) ;
132
133	if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
134	{	if (psf->is_pipe)
135			return SFE_NO_PIPE_WRITE ;
136
137		format = SF_CONTAINER (psf->sf.format) ;
138		if (format != SF_FORMAT_CAF)
139			return	SFE_BAD_OPEN_FORMAT ;
140
141		psf->blockwidth = psf->bytewidth * psf->sf.channels ;
142
143		if (psf->file.mode != SFM_RDWR || psf->filelength < 44)
144		{	psf->filelength = 0 ;
145			psf->datalength = 0 ;
146			psf->dataoffset = 0 ;
147			psf->sf.frames = 0 ;
148			} ;
149
150		psf->strings.flags = SF_STR_ALLOW_START | SF_STR_ALLOW_END ;
151
152		/*
153		**	By default, add the peak chunk to floating point files. Default behaviour
154		**	can be switched off using sf_command (SFC_SET_PEAK_CHUNK, SF_FALSE).
155		*/
156		if (psf->file.mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
157		{	if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
158				return SFE_MALLOC_FAILED ;
159			psf->peak_info->peak_loc = SF_PEAK_START ;
160			} ;
161
162		if ((error = caf_write_header (psf, SF_FALSE)) != 0)
163			return error ;
164
165		psf->write_header	= caf_write_header ;
166		psf->set_chunk		= caf_set_chunk ;
167		} ;
168
169	psf->container_close = caf_close ;
170	psf->command = caf_command ;
171
172	switch (subformat)
173	{	case SF_FORMAT_PCM_S8 :
174		case SF_FORMAT_PCM_16 :
175		case SF_FORMAT_PCM_24 :
176		case SF_FORMAT_PCM_32 :
177					error = pcm_init (psf) ;
178					break ;
179
180		case SF_FORMAT_ULAW :
181					error = ulaw_init (psf) ;
182					break ;
183
184		case SF_FORMAT_ALAW :
185					error = alaw_init (psf) ;
186					break ;
187
188		/* Lite remove start */
189		case SF_FORMAT_FLOAT :
190					error = float32_init (psf) ;
191					break ;
192
193		case SF_FORMAT_DOUBLE :
194					error = double64_init (psf) ;
195					break ;
196
197		case SF_FORMAT_ALAC_16 :
198		case SF_FORMAT_ALAC_20 :
199		case SF_FORMAT_ALAC_24 :
200		case SF_FORMAT_ALAC_32 :
201					if (psf->file.mode == SFM_READ)
202						/* Only pass the ALAC_DECODER_INFO in read mode. */
203						error = alac_init (psf, &pcaf->alac) ;
204					else
205						error = alac_init (psf, NULL) ;
206					break ;
207
208		/* Lite remove end */
209
210		default :
211			return SFE_UNSUPPORTED_ENCODING ;
212		} ;
213
214	return error ;
215} /* caf_open */
216
217static int
218caf_close (SF_PRIVATE *psf)
219{
220	if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
221	{	caf_write_tailer (psf) ;
222		caf_write_header (psf, SF_TRUE) ;
223		} ;
224
225	return 0 ;
226} /* caf_close */
227
228static int
229caf_command (SF_PRIVATE * psf, int command, void * UNUSED (data), int UNUSED (datasize))
230{	CAF_PRIVATE	*pcaf ;
231
232	if ((pcaf = psf->container_data) == NULL)
233		return SFE_INTERNAL ;
234
235	switch (command)
236	{	case SFC_SET_CHANNEL_MAP_INFO :
237			pcaf->chanmap_tag = aiff_caf_find_channel_layout_tag (psf->channel_map, psf->sf.channels) ;
238			return (pcaf->chanmap_tag != 0) ;
239
240		default :
241			break ;
242	} ;
243
244	return 0 ;
245} /* caf_command */
246
247/*------------------------------------------------------------------------------
248*/
249
250static int
251decode_desc_chunk (SF_PRIVATE *psf, const DESC_CHUNK *desc)
252{	int format = SF_FORMAT_CAF ;
253
254	psf->sf.channels = desc->channels_per_frame ;
255
256	if (desc->fmt_id == alac_MARKER)
257	{	CAF_PRIVATE	*pcaf ;
258
259		if ((pcaf = psf->container_data) != NULL)
260		{	switch (desc->fmt_flags)
261			{	case 1 :
262					pcaf->alac.bits_per_sample = 16 ;
263					format |= SF_FORMAT_ALAC_16 ;
264					break ;
265				case 2 :
266					pcaf->alac.bits_per_sample = 20 ;
267					format |= SF_FORMAT_ALAC_20 ;
268					break ;
269				case 3 :
270					pcaf->alac.bits_per_sample = 24 ;
271					format |= SF_FORMAT_ALAC_24 ;
272					break ;
273				case 4 :
274					pcaf->alac.bits_per_sample = 32 ;
275					format |= SF_FORMAT_ALAC_32 ;
276					break ;
277				default :
278					psf_log_printf (psf, "Bad ALAC format flag value of %d\n", desc->fmt_flags) ;
279				} ;
280
281			pcaf->alac.frames_per_packet = desc->frames_per_packet ;
282			} ;
283
284		return format ;
285		} ;
286
287	format |= psf->endian == SF_ENDIAN_LITTLE ? SF_ENDIAN_LITTLE : 0 ;
288
289	if (desc->fmt_id == lpcm_MARKER && desc->fmt_flags & 1)
290	{	/* Floating point data. */
291		if (desc->bits_per_chan == 32 && desc->pkt_bytes == 4 * desc->channels_per_frame)
292		{	psf->bytewidth = 4 ;
293			return format | SF_FORMAT_FLOAT ;
294			} ;
295		if (desc->bits_per_chan == 64 && desc->pkt_bytes == 8 * desc->channels_per_frame)
296		{	psf->bytewidth = 8 ;
297			return format | SF_FORMAT_DOUBLE ;
298			} ;
299		} ;
300
301	if (desc->fmt_id == lpcm_MARKER && (desc->fmt_flags & 1) == 0)
302	{	/* Integer data. */
303		if (desc->bits_per_chan == 32 && desc->pkt_bytes == 4 * desc->channels_per_frame)
304		{	psf->bytewidth = 4 ;
305			return format | SF_FORMAT_PCM_32 ;
306			} ;
307		if (desc->bits_per_chan == 24 && desc->pkt_bytes == 3 * desc->channels_per_frame)
308		{	psf->bytewidth = 3 ;
309			return format | SF_FORMAT_PCM_24 ;
310			} ;
311		if (desc->bits_per_chan == 16 && desc->pkt_bytes == 2 * desc->channels_per_frame)
312		{	psf->bytewidth = 2 ;
313			return format | SF_FORMAT_PCM_16 ;
314			} ;
315		if (desc->bits_per_chan == 8 && desc->pkt_bytes == 1 * desc->channels_per_frame)
316		{	psf->bytewidth = 1 ;
317			return format | SF_FORMAT_PCM_S8 ;
318			} ;
319		} ;
320
321	if (desc->fmt_id == alaw_MARKER && desc->bits_per_chan == 8)
322	{	psf->bytewidth = 1 ;
323		return format | SF_FORMAT_ALAW ;
324		} ;
325
326	if (desc->fmt_id == ulaw_MARKER && desc->bits_per_chan == 8)
327	{	psf->bytewidth = 1 ;
328		return format | SF_FORMAT_ULAW ;
329		} ;
330
331	psf_log_printf (psf, "**** Unknown format identifier.\n") ;
332
333	return 0 ;
334} /* decode_desc_chunk */
335
336static int
337caf_read_header (SF_PRIVATE *psf)
338{	CAF_PRIVATE	*pcaf ;
339	BUF_UNION	ubuf ;
340	DESC_CHUNK desc ;
341	sf_count_t chunk_size ;
342	double srate ;
343	short version, flags ;
344	int marker, k, have_data = 0, error ;
345
346	if ((pcaf = psf->container_data) == NULL)
347		return SFE_INTERNAL ;
348
349	memset (&desc, 0, sizeof (desc)) ;
350
351	/* Set position to start of file to begin reading header. */
352	psf_binheader_readf (psf, "pmE2E2", 0, &marker, &version, &flags) ;
353	psf_log_printf (psf, "%M\n  Version : %d\n  Flags   : %x\n", marker, version, flags) ;
354	if (marker != caff_MARKER)
355		return SFE_CAF_NOT_CAF ;
356
357	psf_binheader_readf (psf, "mE8b", &marker, &chunk_size, ubuf.ucbuf, 8) ;
358	srate = double64_be_read (ubuf.ucbuf) ;
359	snprintf (ubuf.cbuf, sizeof (ubuf.cbuf), "%5.3f", srate) ;
360	psf_log_printf (psf, "%M : %D\n  Sample rate  : %s\n", marker, chunk_size, ubuf.cbuf) ;
361	if (marker != desc_MARKER)
362		return SFE_CAF_NO_DESC ;
363
364	if (chunk_size < SIGNED_SIZEOF (DESC_CHUNK))
365	{	psf_log_printf (psf, "**** Chunk size too small. Should be > 32 bytes.\n") ;
366		return SFE_MALFORMED_FILE ;
367		} ;
368
369	psf->sf.samplerate = psf_lrint (srate) ;
370
371	psf_binheader_readf (psf, "mE44444", &desc.fmt_id, &desc.fmt_flags, &desc.pkt_bytes, &desc.frames_per_packet,
372			&desc.channels_per_frame, &desc.bits_per_chan) ;
373	psf_log_printf (psf, "  Format id    : %M\n  Format flags : %x\n  Bytes / packet   : %u\n"
374			"  Frames / packet  : %u\n  Channels / frame : %u\n  Bits / channel   : %u\n",
375			desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.frames_per_packet, desc.channels_per_frame, desc.bits_per_chan) ;
376
377	if (desc.channels_per_frame > SF_MAX_CHANNELS)
378	{	psf_log_printf (psf, "**** Bad channels per frame value %u.\n", desc.channels_per_frame) ;
379		return SFE_MALFORMED_FILE ;
380		} ;
381
382	if (chunk_size > SIGNED_SIZEOF (DESC_CHUNK))
383		psf_binheader_readf (psf, "j", (int) (chunk_size - sizeof (DESC_CHUNK))) ;
384
385	psf->sf.channels = desc.channels_per_frame ;
386
387	while (1)
388	{	marker = 0 ;
389		chunk_size = 0 ;
390
391		psf_binheader_readf (psf, "mE8", &marker, &chunk_size) ;
392		if (marker == 0)
393		{	sf_count_t pos = psf_ftell (psf) ;
394			psf_log_printf (psf, "Have 0 marker at position %D (0x%x).\n", pos, pos) ;
395			break ;
396			} ;
397		if (chunk_size < 0)
398		{	psf_log_printf (psf, "%M : %D *** Should be >= 0 ***\n", marker, chunk_size) ;
399			break ;
400			} ;
401		if (chunk_size > psf->filelength)
402			break ;
403
404		psf_store_read_chunk_u32 (&psf->rchunks, marker, psf_ftell (psf), chunk_size) ;
405
406		switch (marker)
407		{	case peak_MARKER :
408				psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
409				if (chunk_size != CAF_PEAK_CHUNK_SIZE (psf->sf.channels))
410				{	psf_binheader_readf (psf, "j", (size_t) chunk_size) ;
411					psf_log_printf (psf, "*** File PEAK chunk %D should be %d.\n", chunk_size, CAF_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
412					return SFE_CAF_BAD_PEAK ;
413					} ;
414
415				if (psf->peak_info)
416				{	psf_log_printf (psf, "*** Found existing peak info, using last one.\n") ;
417					free (psf->peak_info) ;
418					psf->peak_info = NULL ;
419					} ;
420				if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
421					return SFE_MALLOC_FAILED ;
422
423				/* read in rest of PEAK chunk. */
424				psf_binheader_readf (psf, "E4", & (psf->peak_info->edit_number)) ;
425				psf_log_printf (psf, "  edit count : %d\n", psf->peak_info->edit_number) ;
426
427				psf_log_printf (psf, "     Ch   Position       Value\n") ;
428				for (k = 0 ; k < psf->sf.channels ; k++)
429				{	sf_count_t position ;
430					float value ;
431
432					psf_binheader_readf (psf, "Ef8", &value, &position) ;
433					psf->peak_info->peaks [k].value = value ;
434					psf->peak_info->peaks [k].position = position ;
435
436					snprintf (ubuf.cbuf, sizeof (ubuf.cbuf), "    %2d   %-12" PRId64 "   %g\n", k, position, value) ;
437					psf_log_printf (psf, ubuf.cbuf) ;
438					} ;
439
440				psf->peak_info->peak_loc = SF_PEAK_START ;
441				break ;
442
443			case chan_MARKER :
444				if (chunk_size < 12)
445				{	psf_log_printf (psf, "%M : %D (should be >= 12)\n", marker, chunk_size) ;
446					psf_binheader_readf (psf, "j", (size_t) chunk_size) ;
447					break ;
448					}
449
450				psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
451
452				if ((error = caf_read_chanmap (psf, chunk_size)))
453					return error ;
454				break ;
455
456			case free_MARKER :
457				psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
458				psf_binheader_readf (psf, "j", (size_t) chunk_size) ;
459				break ;
460
461			case data_MARKER :
462				psf_binheader_readf (psf, "E4", &k) ;
463				if (chunk_size == -1)
464				{	psf_log_printf (psf, "%M : -1\n") ;
465					chunk_size = psf->filelength - psf->header.indx ;
466					}
467				else if (psf->filelength > 0 && chunk_size > psf->filelength - psf->header.indx + 10)
468				{	psf_log_printf (psf, "%M : %D (should be %D)\n", marker, chunk_size, psf->filelength - psf->header.indx - 8) ;
469					psf->datalength = psf->filelength - psf->header.indx - 8 ;
470					}
471				else
472				{	psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
473					/* Subtract the 4 bytes of the 'edit' field above. */
474					psf->datalength = chunk_size - 4 ;
475					} ;
476
477				psf_log_printf (psf, "  edit : %u\n", k) ;
478
479				psf->dataoffset = psf->header.indx ;
480				if (psf->datalength + psf->dataoffset < psf->filelength)
481					psf->dataend = psf->datalength + psf->dataoffset ;
482
483				psf_binheader_readf (psf, "j", (size_t) psf->datalength) ;
484				have_data = 1 ;
485				break ;
486
487			case kuki_MARKER :
488				psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
489				pcaf->alac.kuki_offset = psf_ftell (psf) - 12 ;
490				psf_binheader_readf (psf, "j", (size_t) chunk_size) ;
491				break ;
492
493			case pakt_MARKER :
494				if (chunk_size < 24)
495				{	psf_log_printf (psf, "%M : %D (should be > 24)\n", marker, chunk_size) ;
496					return SFE_MALFORMED_FILE ;
497					}
498				else if (chunk_size > psf->filelength - psf->header.indx)
499				{	psf_log_printf (psf, "%M : %D (should be < %D)\n", marker, chunk_size, psf->filelength - psf->header.indx) ;
500					return SFE_MALFORMED_FILE ;
501					}
502				else
503					psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
504
505				psf_binheader_readf (psf, "E8844", &pcaf->alac.packets, &pcaf->alac.valid_frames,
506									&pcaf->alac.priming_frames, &pcaf->alac.remainder_frames) ;
507
508				psf_log_printf (psf,
509						"  Packets          : %D\n"
510						"  Valid frames     : %D\n"
511						"  Priming frames   : %d\n"
512						"  Remainder frames : %d\n",
513						pcaf->alac.packets, pcaf->alac.valid_frames, pcaf->alac.priming_frames,
514						pcaf->alac.remainder_frames
515						) ;
516
517				if (pcaf->alac.packets == 0 && pcaf->alac.valid_frames == 0
518							&& pcaf->alac.priming_frames == 0 && pcaf->alac.remainder_frames == 0)
519					psf_log_printf (psf, "*** 'pakt' chunk header is all zero.\n") ;
520
521				pcaf->alac.pakt_offset = psf_ftell (psf) - 12 ;
522				psf_binheader_readf (psf, "j", (size_t) chunk_size - 24) ;
523				break ;
524
525			case info_MARKER :
526				if (chunk_size < 4)
527				{	psf_log_printf (psf, "%M : %D (should be > 4)\n", marker, chunk_size) ;
528					return SFE_MALFORMED_FILE ;
529					}
530				else if (chunk_size > psf->filelength - psf->header.indx)
531				{	psf_log_printf (psf, "%M : %D (should be < %D)\n", marker, chunk_size, psf->filelength - psf->header.indx) ;
532					return SFE_MALFORMED_FILE ;
533					} ;
534				psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
535				if (chunk_size > 4)
536					caf_read_strings (psf, chunk_size - 4) ;
537				break ;
538
539			default :
540				psf_log_printf (psf, "%M : %D (skipped)\n", marker, chunk_size) ;
541				psf_binheader_readf (psf, "j", (size_t) chunk_size) ;
542				break ;
543			} ;
544
545		if (marker != data_MARKER && chunk_size >= 0xffffff00)
546			break ;
547
548		if (! psf->sf.seekable && have_data)
549			break ;
550
551		if (psf_ftell (psf) >= psf->filelength - SIGNED_SIZEOF (chunk_size))
552		{	psf_log_printf (psf, "End\n") ;
553			break ;
554			} ;
555		} ;
556
557	if (have_data == 0)
558	{	psf_log_printf (psf, "**** Error, could not find 'data' chunk.\n") ;
559		return SFE_MALFORMED_FILE ;
560		} ;
561
562	psf->endian = (desc.fmt_flags & 2) ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ;
563
564	psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
565
566	if ((psf->sf.format = decode_desc_chunk (psf, &desc)) == 0)
567		return SFE_UNSUPPORTED_ENCODING ;
568
569	if (psf->bytewidth > 0)
570		psf->sf.frames = psf->datalength / psf->bytewidth ;
571
572	return 0 ;
573} /* caf_read_header */
574
575/*------------------------------------------------------------------------------
576*/
577
578static int
579caf_write_header (SF_PRIVATE *psf, int calc_length)
580{	BUF_UNION	ubuf ;
581	CAF_PRIVATE	*pcaf ;
582	DESC_CHUNK desc ;
583	sf_count_t current ;
584	uint32_t uk ;
585	int subformat, append_free_block = SF_TRUE ;
586
587	if ((pcaf = psf->container_data) == NULL)
588		return SFE_INTERNAL ;
589
590	memset (&desc, 0, sizeof (desc)) ;
591
592	current = psf_ftell (psf) ;
593
594	if (calc_length)
595	{	psf->filelength = psf_get_filelen (psf) ;
596
597		psf->datalength = psf->filelength - psf->dataoffset ;
598
599		if (psf->dataend)
600			psf->datalength -= psf->filelength - psf->dataend ;
601
602		if (psf->bytewidth > 0)
603			psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
604		} ;
605
606	/* Reset the current header length to zero. */
607	psf->header.ptr [0] = 0 ;
608	psf->header.indx = 0 ;
609	psf_fseek (psf, 0, SEEK_SET) ;
610
611	/* 'caff' marker, version and flags. */
612	psf_binheader_writef (psf, "Em22", BHWm (caff_MARKER), BHW2 (1), BHW2 (0)) ;
613
614	/* 'desc' marker and chunk size. */
615	psf_binheader_writef (psf, "Em8", BHWm (desc_MARKER), BHW8 ((sf_count_t) (sizeof (DESC_CHUNK)))) ;
616
617 	double64_be_write (1.0 * psf->sf.samplerate, ubuf.ucbuf) ;
618	psf_binheader_writef (psf, "b", BHWv (ubuf.ucbuf), BHWz (8)) ;
619
620	subformat = SF_CODEC (psf->sf.format) ;
621
622	psf->endian = SF_ENDIAN (psf->sf.format) ;
623
624	if (CPU_IS_BIG_ENDIAN && (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU))
625		psf->endian = SF_ENDIAN_BIG ;
626	else if (CPU_IS_LITTLE_ENDIAN && (psf->endian == SF_ENDIAN_LITTLE || psf->endian == SF_ENDIAN_CPU))
627		psf->endian = SF_ENDIAN_LITTLE ;
628
629	if (psf->endian == SF_ENDIAN_LITTLE)
630		desc.fmt_flags = 2 ;
631	else
632		psf->endian = SF_ENDIAN_BIG ;
633
634	/* initial section (same for all, it appears) */
635	switch (subformat)
636	{	case SF_FORMAT_PCM_S8 :
637			desc.fmt_id = lpcm_MARKER ;
638			psf->bytewidth = 1 ;
639			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
640			desc.frames_per_packet = 1 ;
641			desc.channels_per_frame = psf->sf.channels ;
642			desc.bits_per_chan = 8 ;
643			break ;
644
645		case SF_FORMAT_PCM_16 :
646			desc.fmt_id = lpcm_MARKER ;
647			psf->bytewidth = 2 ;
648			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
649			desc.frames_per_packet = 1 ;
650			desc.channels_per_frame = psf->sf.channels ;
651			desc.bits_per_chan = 16 ;
652			break ;
653
654		case SF_FORMAT_PCM_24 :
655			psf->bytewidth = 3 ;
656			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
657			desc.frames_per_packet = 1 ;
658			desc.channels_per_frame = psf->sf.channels ;
659			desc.bits_per_chan = 24 ;
660			desc.fmt_id = lpcm_MARKER ;
661			break ;
662
663		case SF_FORMAT_PCM_32 :
664			desc.fmt_id = lpcm_MARKER ;
665			psf->bytewidth = 4 ;
666			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
667			desc.frames_per_packet = 1 ;
668			desc.channels_per_frame = psf->sf.channels ;
669			desc.bits_per_chan = 32 ;
670			break ;
671
672		case SF_FORMAT_FLOAT :
673			desc.fmt_id = lpcm_MARKER ;
674			desc.fmt_flags |= 1 ;
675			psf->bytewidth = 4 ;
676			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
677			desc.frames_per_packet = 1 ;
678			desc.channels_per_frame = psf->sf.channels ;
679			desc.bits_per_chan = 32 ;
680			break ;
681
682		case SF_FORMAT_DOUBLE :
683			desc.fmt_id = lpcm_MARKER ;
684			desc.fmt_flags |= 1 ;
685			psf->bytewidth = 8 ;
686			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
687			desc.frames_per_packet = 1 ;
688			desc.channels_per_frame = psf->sf.channels ;
689			desc.bits_per_chan = 64 ;
690			break ;
691
692		case SF_FORMAT_ALAW :
693			desc.fmt_id = alaw_MARKER ;
694			psf->bytewidth = 1 ;
695			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
696			desc.frames_per_packet = 1 ;
697			desc.channels_per_frame = psf->sf.channels ;
698			desc.bits_per_chan = 8 ;
699			break ;
700
701		case SF_FORMAT_ULAW :
702			desc.fmt_id = ulaw_MARKER ;
703			psf->bytewidth = 1 ;
704			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
705			desc.frames_per_packet = 1 ;
706			desc.channels_per_frame = psf->sf.channels ;
707			desc.bits_per_chan = 8 ;
708			break ;
709
710		case SF_FORMAT_ALAC_16 :
711		case SF_FORMAT_ALAC_20 :
712		case SF_FORMAT_ALAC_24 :
713		case SF_FORMAT_ALAC_32 :
714			desc.fmt_id = alac_MARKER ;
715			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
716			desc.channels_per_frame = psf->sf.channels ;
717			alac_get_desc_chunk_items (subformat, &desc.fmt_flags, &desc.frames_per_packet) ;
718			append_free_block = SF_FALSE ;
719			break ;
720
721		default :
722			return SFE_UNIMPLEMENTED ;
723		} ;
724
725	psf_binheader_writef (psf, "mE44444", BHWm (desc.fmt_id), BHW4 (desc.fmt_flags), BHW4 (desc.pkt_bytes), BHW4 (desc.frames_per_packet), BHW4 (desc.channels_per_frame), BHW4 (desc.bits_per_chan)) ;
726
727	caf_write_strings (psf, SF_STR_LOCATE_START) ;
728
729	if (psf->peak_info != NULL)
730	{	int k ;
731		psf_binheader_writef (psf, "Em84", BHWm (peak_MARKER), BHW8 ((sf_count_t) CAF_PEAK_CHUNK_SIZE (psf->sf.channels)), BHW4 (psf->peak_info->edit_number)) ;
732		for (k = 0 ; k < psf->sf.channels ; k++)
733			psf_binheader_writef (psf, "Ef8", BHWf ((float) psf->peak_info->peaks [k].value), BHW8 (psf->peak_info->peaks [k].position)) ;
734		} ;
735
736	if (psf->channel_map && pcaf->chanmap_tag)
737		psf_binheader_writef (psf, "Em8444", BHWm (chan_MARKER), BHW8 ((sf_count_t) 12), BHW4 (pcaf->chanmap_tag), BHW4 (0), BHW4 (0)) ;
738
739	/* Write custom headers. */
740	for (uk = 0 ; uk < psf->wchunks.used ; uk++)
741		psf_binheader_writef (psf, "m44b", BHWm ((int) psf->wchunks.chunks [uk].mark32), BHW4 (0), BHW4 (psf->wchunks.chunks [uk].len), BHWv (psf->wchunks.chunks [uk].data), BHWz (psf->wchunks.chunks [uk].len)) ;
742
743	if (append_free_block)
744	{	/* Add free chunk so that the actual audio data starts at a multiple 0x1000. */
745		sf_count_t free_len = 0x1000 - psf->header.indx - 16 - 12 ;
746		while (free_len < 0)
747			free_len += 0x1000 ;
748		psf_binheader_writef (psf, "Em8z", BHWm (free_MARKER), BHW8 (free_len), BHWz (free_len)) ;
749		} ;
750
751	psf_binheader_writef (psf, "Em84", BHWm (data_MARKER), BHW8 (psf->datalength + 4), BHW4 (0)) ;
752
753	psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ;
754	if (psf->error)
755		return psf->error ;
756
757	psf->dataoffset = psf->header.indx ;
758	if (current < psf->dataoffset)
759		psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
760	else if (current > 0)
761		psf_fseek (psf, current, SEEK_SET) ;
762
763	return psf->error ;
764} /* caf_write_header */
765
766static int
767caf_write_tailer (SF_PRIVATE *psf)
768{
769	/* Reset the current header buffer length to zero. */
770	psf->header.ptr [0] = 0 ;
771	psf->header.indx = 0 ;
772
773	if (psf->bytewidth > 0 && psf->sf.seekable == SF_TRUE)
774	{	psf->datalength = psf->sf.frames * psf->bytewidth * psf->sf.channels ;
775		psf->dataend = psf->dataoffset + psf->datalength ;
776		} ;
777
778	if (psf->dataend > 0)
779		psf_fseek (psf, psf->dataend, SEEK_SET) ;
780	else
781		psf->dataend = psf_fseek (psf, 0, SEEK_END) ;
782
783	if (psf->dataend & 1)
784		psf_binheader_writef (psf, "z", BHWz (1)) ;
785
786	if (psf->strings.flags & SF_STR_LOCATE_END)
787		caf_write_strings (psf, SF_STR_LOCATE_END) ;
788
789	/* Write the tailer. */
790	if (psf->header.indx > 0)
791		psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ;
792
793	return 0 ;
794} /* caf_write_tailer */
795
796static int
797caf_read_chanmap (SF_PRIVATE * psf, sf_count_t chunk_size)
798{	const AIFF_CAF_CHANNEL_MAP * map_info ;
799	unsigned channel_bitmap, channel_decriptions, bytesread ;
800	int layout_tag ;
801
802	bytesread = psf_binheader_readf (psf, "E444", &layout_tag, &channel_bitmap, &channel_decriptions) ;
803
804	map_info = aiff_caf_of_channel_layout_tag (layout_tag) ;
805
806	psf_log_printf (psf, "  Tag    : %x\n", layout_tag) ;
807	if (map_info)
808		psf_log_printf (psf, "  Layout : %s\n", map_info->name) ;
809
810	if (bytesread < chunk_size)
811		psf_binheader_readf (psf, "j", chunk_size - bytesread) ;
812
813	if (map_info && map_info->channel_map != NULL)
814	{	size_t chanmap_size = SF_MIN (psf->sf.channels, layout_tag & 0xff) * sizeof (psf->channel_map [0]) ;
815
816		free (psf->channel_map) ;
817
818		if ((psf->channel_map = malloc (chanmap_size)) == NULL)
819			return SFE_MALLOC_FAILED ;
820
821		memcpy (psf->channel_map, map_info->channel_map, chanmap_size) ;
822		} ;
823
824	return 0 ;
825} /* caf_read_chanmap */
826
827
828static uint32_t
829string_hash32 (const char * str)
830{	uint32_t hash = 0x87654321 ;
831
832	while (str [0])
833	{	hash = hash * 333 + str [0] ;
834		str ++ ;
835		} ;
836
837	return hash ;
838} /* string_hash32 */
839
840static int
841caf_read_strings (SF_PRIVATE * psf, sf_count_t chunk_size)
842{	char *buf ;
843	char *key, *value ;
844	uint32_t count, hash ;
845
846	if ((buf = malloc (chunk_size + 1)) == NULL)
847		return (psf->error = SFE_MALLOC_FAILED) ;
848
849	psf_binheader_readf (psf, "E4b", &count, buf, (size_t) chunk_size) ;
850	psf_log_printf (psf, " count: %u\n", count) ;
851
852	/* Force terminate `buf` to make sure. */
853	buf [chunk_size] = 0 ;
854
855	for (key = buf ; key < buf + chunk_size ; )
856	{	value = key + strlen (key) + 1 ;
857		if (value > buf + chunk_size)
858			break ;
859		psf_log_printf (psf, "   %-12s : %s\n", key, value) ;
860
861		hash = string_hash32 (key) ;
862		switch (hash)
863		{	case 0xC4861943 : /* 'title' */
864				psf_store_string (psf, SF_STR_TITLE, value) ;
865				break ;
866			case 0xAD47A394 : /* 'software' */
867				psf_store_string (psf, SF_STR_SOFTWARE, value) ;
868				break ;
869			case 0x5D178E2A : /* 'copyright' */
870				psf_store_string (psf, SF_STR_COPYRIGHT, value) ;
871				break ;
872			case 0x60E4D0C8 : /* 'artist' */
873				psf_store_string (psf, SF_STR_ARTIST, value) ;
874				break ;
875			case 0x83B5D16A : /* 'genre' */
876				psf_store_string (psf, SF_STR_GENRE, value) ;
877				break ;
878			case 0x15E5FC88 : /* 'comment' */
879			case 0x7C297D5B : /* 'comments' */
880				psf_store_string (psf, SF_STR_COMMENT, value) ;
881				break ;
882			case 0x24A7C347 : /* 'tracknumber' */
883				psf_store_string (psf, SF_STR_TRACKNUMBER, value) ;
884				break ;
885			case 0x50A31EB7 : /* 'date' */
886				psf_store_string (psf, SF_STR_DATE, value) ;
887				break ;
888			case 0x6583545A : /* 'album' */
889				psf_store_string (psf, SF_STR_ALBUM, value) ;
890				break ;
891			case 0xE7C64B6C : /* 'license' */
892				psf_store_string (psf, SF_STR_LICENSE, value) ;
893				break ;
894			default :
895				psf_log_printf (psf, " Unhandled hash 0x%x : /* '%s' */\n", hash, key) ;
896				break ;
897			} ;
898
899		key = value + strlen (value) + 1 ;
900		} ;
901
902	free (buf) ;
903
904	return 0 ;
905} /* caf_read_strings */
906
907struct put_buffer
908{	uint32_t index ;
909	char s [16 * 1024] ;
910} ;
911
912static uint32_t
913put_key_value (struct put_buffer * buf, const char * key, const char * value)
914{	uint32_t written ;
915
916	if (buf->index + strlen (key) + strlen (value) + 2 > sizeof (buf->s))
917		return 0 ;
918
919	written = snprintf (buf->s + buf->index, sizeof (buf->s) - buf->index, "%s%c%s%c", key, 0, value, 0) ;
920
921	if (buf->index + written >= sizeof (buf->s))
922		return 0 ;
923
924	buf->index += written ;
925	return 1 ;
926} /* put_key_value */
927
928static void
929caf_write_strings (SF_PRIVATE * psf, int location)
930{	struct put_buffer buf ;
931 	const char * cptr ;
932	uint32_t k, string_count = 0 ;
933
934	memset (&buf, 0, sizeof (buf)) ;
935
936	for (k = 0 ; k < SF_MAX_STRINGS ; k++)
937	{	if (psf->strings.data [k].type == 0)
938			break ;
939
940		if (psf->strings.data [k].flags != location)
941			continue ;
942
943		if ((cptr = psf_get_string (psf, psf->strings.data [k].type)) == NULL)
944			continue ;
945
946		switch (psf->strings.data [k].type)
947		{	case SF_STR_TITLE :
948				string_count += put_key_value (&buf, "title", cptr) ;
949				break ;
950			case SF_STR_COPYRIGHT :
951				string_count += put_key_value (&buf, "copyright", cptr) ;
952				break ;
953			case SF_STR_SOFTWARE :
954				string_count += put_key_value (&buf, "software", cptr) ;
955				break ;
956			case SF_STR_ARTIST :
957				string_count += put_key_value (&buf, "artist", cptr) ;
958				break ;
959			case SF_STR_COMMENT :
960				string_count += put_key_value (&buf, "comment", cptr) ;
961				break ;
962			case SF_STR_DATE :
963				string_count += put_key_value (&buf, "date", cptr) ;
964				break ;
965			case SF_STR_ALBUM :
966				string_count += put_key_value (&buf, "album", cptr) ;
967				break ;
968			case SF_STR_LICENSE :
969				string_count += put_key_value (&buf, "license", cptr) ;
970				break ;
971			case SF_STR_TRACKNUMBER :
972				string_count += put_key_value (&buf, "tracknumber", cptr) ;
973				break ;
974			case SF_STR_GENRE :
975				string_count += put_key_value (&buf, "genre", cptr) ;
976				break ;
977
978			default :
979				break ;
980			} ;
981		} ;
982
983	if (string_count == 0 || buf.index == 0)
984		return ;
985
986	psf_binheader_writef (psf, "Em84b", BHWm (info_MARKER), BHW8 (buf.index + 4), BHW4 (string_count), BHWv (buf.s), BHWz (buf.index)) ;
987} /* caf_write_strings */
988
989/*==============================================================================
990*/
991
992static int
993caf_set_chunk (SF_PRIVATE *psf, const SF_CHUNK_INFO * chunk_info)
994{	return psf_save_write_chunk (&psf->wchunks, chunk_info) ;
995} /* caf_set_chunk */
996
997static SF_CHUNK_ITERATOR *
998caf_next_chunk_iterator (SF_PRIVATE *psf, SF_CHUNK_ITERATOR * iterator)
999{	return psf_next_chunk_iterator (&psf->rchunks, iterator) ;
1000} /* caf_next_chunk_iterator */
1001
1002static int
1003caf_get_chunk_size (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info)
1004{	int indx ;
1005
1006	if ((indx = psf_find_read_chunk_iterator (&psf->rchunks, iterator)) < 0)
1007		return SFE_UNKNOWN_CHUNK ;
1008
1009	chunk_info->datalen = psf->rchunks.chunks [indx].len ;
1010
1011	return SFE_NO_ERROR ;
1012} /* caf_get_chunk_size */
1013
1014static int
1015caf_get_chunk_data (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info)
1016{	int indx ;
1017	sf_count_t pos ;
1018
1019	if ((indx = psf_find_read_chunk_iterator (&psf->rchunks, iterator)) < 0)
1020		return SFE_UNKNOWN_CHUNK ;
1021
1022	if (chunk_info->data == NULL)
1023		return SFE_BAD_CHUNK_DATA_PTR ;
1024
1025	chunk_info->id_size = psf->rchunks.chunks [indx].id_size ;
1026	memcpy (chunk_info->id, psf->rchunks.chunks [indx].id, sizeof (chunk_info->id) / sizeof (*chunk_info->id)) ;
1027
1028	pos = psf_ftell (psf) ;
1029	psf_fseek (psf, psf->rchunks.chunks [indx].offset, SEEK_SET) ;
1030	psf_fread (chunk_info->data, SF_MIN (chunk_info->datalen, psf->rchunks.chunks [indx].len), 1, psf) ;
1031	psf_fseek (psf, pos, SEEK_SET) ;
1032
1033	return SFE_NO_ERROR ;
1034} /* caf_get_chunk_data */
1035