File: | libs/libsndfile/src/caf.c |
Location: | line 745, column 6 |
Description: | Access to field 'channel_map' results in a dereference of a null pointer (loaded from variable 'map_info') |
1 | /* | |||
2 | ** Copyright (C) 2005-2013 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 | #ifdef HAVE_INTTYPES_H1 | |||
27 | #include <inttypes.h> | |||
28 | #endif | |||
29 | ||||
30 | #include "sndfile.h" | |||
31 | #include "sfendian.h" | |||
32 | #include "common.h" | |||
33 | #include "chanmap.h" | |||
34 | ||||
35 | /*------------------------------------------------------------------------------ | |||
36 | ** Macros to handle big/little endian issues. | |||
37 | */ | |||
38 | ||||
39 | #define aac_MARKER((uint32_t) (('a') | (('a') << 8) | (('c') << 16) | (((uint32_t) (' ')) << 24))) MAKE_MARKER ('a', 'a', 'c', ' ')((uint32_t) (('a') | (('a') << 8) | (('c') << 16) | (((uint32_t) (' ')) << 24))) | |||
40 | #define alac_MARKER((uint32_t) (('a') | (('l') << 8) | (('a') << 16) | (((uint32_t) ('c')) << 24))) MAKE_MARKER ('a', 'l', 'a', 'c')((uint32_t) (('a') | (('l') << 8) | (('a') << 16) | (((uint32_t) ('c')) << 24))) | |||
41 | #define alaw_MARKER((uint32_t) (('a') | (('l') << 8) | (('a') << 16) | (((uint32_t) ('w')) << 24))) MAKE_MARKER ('a', 'l', 'a', 'w')((uint32_t) (('a') | (('l') << 8) | (('a') << 16) | (((uint32_t) ('w')) << 24))) | |||
42 | #define caff_MARKER((uint32_t) (('c') | (('a') << 8) | (('f') << 16) | (((uint32_t) ('f')) << 24))) MAKE_MARKER ('c', 'a', 'f', 'f')((uint32_t) (('c') | (('a') << 8) | (('f') << 16) | (((uint32_t) ('f')) << 24))) | |||
43 | #define chan_MARKER((uint32_t) (('c') | (('h') << 8) | (('a') << 16) | (((uint32_t) ('n')) << 24))) MAKE_MARKER ('c', 'h', 'a', 'n')((uint32_t) (('c') | (('h') << 8) | (('a') << 16) | (((uint32_t) ('n')) << 24))) | |||
44 | #define data_MARKER((uint32_t) (('d') | (('a') << 8) | (('t') << 16) | (((uint32_t) ('a')) << 24))) MAKE_MARKER ('d', 'a', 't', 'a')((uint32_t) (('d') | (('a') << 8) | (('t') << 16) | (((uint32_t) ('a')) << 24))) | |||
45 | #define desc_MARKER((uint32_t) (('d') | (('e') << 8) | (('s') << 16) | (((uint32_t) ('c')) << 24))) MAKE_MARKER ('d', 'e', 's', 'c')((uint32_t) (('d') | (('e') << 8) | (('s') << 16) | (((uint32_t) ('c')) << 24))) | |||
46 | #define edct_MARKER((uint32_t) (('e') | (('d') << 8) | (('c') << 16) | (((uint32_t) ('t')) << 24))) MAKE_MARKER ('e', 'd', 'c', 't')((uint32_t) (('e') | (('d') << 8) | (('c') << 16) | (((uint32_t) ('t')) << 24))) | |||
47 | #define free_MARKER((uint32_t) (('f') | (('r') << 8) | (('e') << 16) | (((uint32_t) ('e')) << 24))) MAKE_MARKER ('f', 'r', 'e', 'e')((uint32_t) (('f') | (('r') << 8) | (('e') << 16) | (((uint32_t) ('e')) << 24))) | |||
48 | #define ima4_MARKER((uint32_t) (('i') | (('m') << 8) | (('a') << 16) | (((uint32_t) ('4')) << 24))) MAKE_MARKER ('i', 'm', 'a', '4')((uint32_t) (('i') | (('m') << 8) | (('a') << 16) | (((uint32_t) ('4')) << 24))) | |||
49 | #define info_MARKER((uint32_t) (('i') | (('n') << 8) | (('f') << 16) | (((uint32_t) ('o')) << 24))) MAKE_MARKER ('i', 'n', 'f', 'o')((uint32_t) (('i') | (('n') << 8) | (('f') << 16) | (((uint32_t) ('o')) << 24))) | |||
50 | #define inst_MARKER((uint32_t) (('i') | (('n') << 8) | (('s') << 16) | (((uint32_t) ('t')) << 24))) MAKE_MARKER ('i', 'n', 's', 't')((uint32_t) (('i') | (('n') << 8) | (('s') << 16) | (((uint32_t) ('t')) << 24))) | |||
51 | #define kuki_MARKER((uint32_t) (('k') | (('u') << 8) | (('k') << 16) | (((uint32_t) ('i')) << 24))) MAKE_MARKER ('k', 'u', 'k', 'i')((uint32_t) (('k') | (('u') << 8) | (('k') << 16) | (((uint32_t) ('i')) << 24))) | |||
52 | #define lpcm_MARKER((uint32_t) (('l') | (('p') << 8) | (('c') << 16) | (((uint32_t) ('m')) << 24))) MAKE_MARKER ('l', 'p', 'c', 'm')((uint32_t) (('l') | (('p') << 8) | (('c') << 16) | (((uint32_t) ('m')) << 24))) | |||
53 | #define mark_MARKER((uint32_t) (('m') | (('a') << 8) | (('r') << 16) | (((uint32_t) ('k')) << 24))) MAKE_MARKER ('m', 'a', 'r', 'k')((uint32_t) (('m') | (('a') << 8) | (('r') << 16) | (((uint32_t) ('k')) << 24))) | |||
54 | #define midi_MARKER((uint32_t) (('m') | (('i') << 8) | (('d') << 16) | (((uint32_t) ('i')) << 24))) MAKE_MARKER ('m', 'i', 'd', 'i')((uint32_t) (('m') | (('i') << 8) | (('d') << 16) | (((uint32_t) ('i')) << 24))) | |||
55 | #define mp1_MARKER((uint32_t) (('.') | (('m') << 8) | (('p') << 16) | (((uint32_t) ('1')) << 24))) MAKE_MARKER ('.', 'm', 'p', '1')((uint32_t) (('.') | (('m') << 8) | (('p') << 16) | (((uint32_t) ('1')) << 24))) | |||
56 | #define mp2_MARKER((uint32_t) (('.') | (('m') << 8) | (('p') << 16) | (((uint32_t) ('2')) << 24))) MAKE_MARKER ('.', 'm', 'p', '2')((uint32_t) (('.') | (('m') << 8) | (('p') << 16) | (((uint32_t) ('2')) << 24))) | |||
57 | #define mp3_MARKER((uint32_t) (('.') | (('m') << 8) | (('p') << 16) | (((uint32_t) ('3')) << 24))) MAKE_MARKER ('.', 'm', 'p', '3')((uint32_t) (('.') | (('m') << 8) | (('p') << 16) | (((uint32_t) ('3')) << 24))) | |||
58 | #define ovvw_MARKER((uint32_t) (('o') | (('v') << 8) | (('v') << 16) | (((uint32_t) ('w')) << 24))) MAKE_MARKER ('o', 'v', 'v', 'w')((uint32_t) (('o') | (('v') << 8) | (('v') << 16) | (((uint32_t) ('w')) << 24))) | |||
59 | #define pakt_MARKER((uint32_t) (('p') | (('a') << 8) | (('k') << 16) | (((uint32_t) ('t')) << 24))) MAKE_MARKER ('p', 'a', 'k', 't')((uint32_t) (('p') | (('a') << 8) | (('k') << 16) | (((uint32_t) ('t')) << 24))) | |||
60 | #define peak_MARKER((uint32_t) (('p') | (('e') << 8) | (('a') << 16) | (((uint32_t) ('k')) << 24))) MAKE_MARKER ('p', 'e', 'a', 'k')((uint32_t) (('p') | (('e') << 8) | (('a') << 16) | (((uint32_t) ('k')) << 24))) | |||
61 | #define regn_MARKER((uint32_t) (('r') | (('e') << 8) | (('g') << 16) | (((uint32_t) ('n')) << 24))) MAKE_MARKER ('r', 'e', 'g', 'n')((uint32_t) (('r') | (('e') << 8) | (('g') << 16) | (((uint32_t) ('n')) << 24))) | |||
62 | #define strg_MARKER((uint32_t) (('s') | (('t') << 8) | (('r') << 16) | (((uint32_t) ('g')) << 24))) MAKE_MARKER ('s', 't', 'r', 'g')((uint32_t) (('s') | (('t') << 8) | (('r') << 16) | (((uint32_t) ('g')) << 24))) | |||
63 | #define umid_MARKER((uint32_t) (('u') | (('m') << 8) | (('i') << 16) | (((uint32_t) ('d')) << 24))) MAKE_MARKER ('u', 'm', 'i', 'd')((uint32_t) (('u') | (('m') << 8) | (('i') << 16) | (((uint32_t) ('d')) << 24))) | |||
64 | #define uuid_MARKER((uint32_t) (('u') | (('u') << 8) | (('i') << 16) | (((uint32_t) ('d')) << 24))) MAKE_MARKER ('u', 'u', 'i', 'd')((uint32_t) (('u') | (('u') << 8) | (('i') << 16) | (((uint32_t) ('d')) << 24))) | |||
65 | #define ulaw_MARKER((uint32_t) (('u') | (('l') << 8) | (('a') << 16) | (((uint32_t) ('w')) << 24))) MAKE_MARKER ('u', 'l', 'a', 'w')((uint32_t) (('u') | (('l') << 8) | (('a') << 16) | (((uint32_t) ('w')) << 24))) | |||
66 | #define MAC3_MARKER((uint32_t) (('M') | (('A') << 8) | (('C') << 16) | (((uint32_t) ('3')) << 24))) MAKE_MARKER ('M', 'A', 'C', '3')((uint32_t) (('M') | (('A') << 8) | (('C') << 16) | (((uint32_t) ('3')) << 24))) | |||
67 | #define MAC6_MARKER((uint32_t) (('M') | (('A') << 8) | (('C') << 16) | (((uint32_t) ('6')) << 24))) MAKE_MARKER ('M', 'A', 'C', '6')((uint32_t) (('M') | (('A') << 8) | (('C') << 16) | (((uint32_t) ('6')) << 24))) | |||
68 | ||||
69 | #define CAF_PEAK_CHUNK_SIZE(ch)((int) (sizeof (int) + ch * (sizeof (float) + 8))) ((int) (sizeof (int) + ch * (sizeof (float) + 8))) | |||
70 | ||||
71 | #define SFE_CAF_NOT_CAF666 666 | |||
72 | #define SFE_CAF_NO_DESC667 667 | |||
73 | #define SFE_CAF_BAD_PEAK668 668 | |||
74 | ||||
75 | /*------------------------------------------------------------------------------ | |||
76 | ** Typedefs. | |||
77 | */ | |||
78 | ||||
79 | typedef struct | |||
80 | { uint8_t srate [8] ; | |||
81 | uint32_t fmt_id ; | |||
82 | uint32_t fmt_flags ; | |||
83 | uint32_t pkt_bytes ; | |||
84 | uint32_t frames_per_packet ; | |||
85 | uint32_t channels_per_frame ; | |||
86 | uint32_t bits_per_chan ; | |||
87 | } DESC_CHUNK ; | |||
88 | ||||
89 | typedef struct | |||
90 | { int chanmap_tag ; | |||
91 | ||||
92 | ALAC_DECODER_INFO alac ; | |||
93 | } CAF_PRIVATE ; | |||
94 | ||||
95 | /*------------------------------------------------------------------------------ | |||
96 | ** Private static functions. | |||
97 | */ | |||
98 | ||||
99 | static int caf_close (SF_PRIVATE *psf) ; | |||
100 | static int caf_read_header (SF_PRIVATE *psf) ; | |||
101 | static int caf_write_header (SF_PRIVATE *psf, int calc_length) ; | |||
102 | static int caf_command (SF_PRIVATE *psf, int command, void *data, int datasize) ; | |||
103 | static int caf_read_chanmap (SF_PRIVATE * psf, sf_count_t chunk_size) ; | |||
104 | ||||
105 | static int caf_set_chunk (SF_PRIVATE *psf, const SF_CHUNK_INFO * chunk_info) ; | |||
106 | static SF_CHUNK_ITERATOR * caf_next_chunk_iterator (SF_PRIVATE *psf, SF_CHUNK_ITERATOR * iterator) ; | |||
107 | static int caf_get_chunk_size (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) ; | |||
108 | static int caf_get_chunk_data (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) ; | |||
109 | ||||
110 | /*------------------------------------------------------------------------------ | |||
111 | ** Public function. | |||
112 | */ | |||
113 | ||||
114 | int | |||
115 | caf_open (SF_PRIVATE *psf) | |||
116 | { CAF_PRIVATE * pcaf ; | |||
117 | int subformat, format, error = 0 ; | |||
118 | ||||
119 | if ((psf->container_data = calloc (1, sizeof (CAF_PRIVATE))) == NULL((void*)0)) | |||
120 | return SFE_MALLOC_FAILED ; | |||
121 | ||||
122 | pcaf = psf->container_data ; | |||
123 | ||||
124 | if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0)) | |||
125 | { if ((error = caf_read_header (psf))) | |||
126 | return error ; | |||
127 | ||||
128 | psf->next_chunk_iterator = caf_next_chunk_iterator ; | |||
129 | psf->get_chunk_size = caf_get_chunk_size ; | |||
130 | psf->get_chunk_data = caf_get_chunk_data ; | |||
131 | } ; | |||
132 | ||||
133 | subformat = SF_CODEC (psf->sf.format)((psf->sf.format) & SF_FORMAT_SUBMASK) ; | |||
134 | ||||
135 | if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) | |||
136 | { if (psf->is_pipe) | |||
137 | return SFE_NO_PIPE_WRITE ; | |||
138 | ||||
139 | format = SF_CONTAINER (psf->sf.format)((psf->sf.format) & SF_FORMAT_TYPEMASK) ; | |||
140 | if (format != SF_FORMAT_CAF) | |||
141 | return SFE_BAD_OPEN_FORMAT ; | |||
142 | ||||
143 | psf->blockwidth = psf->bytewidth * psf->sf.channels ; | |||
144 | ||||
145 | if (psf->file.mode != SFM_RDWR || psf->filelength < 44) | |||
146 | { psf->filelength = 0 ; | |||
147 | psf->datalength = 0 ; | |||
148 | psf->dataoffset = 0 ; | |||
149 | psf->sf.frames = 0 ; | |||
150 | } ; | |||
151 | ||||
152 | psf->strings.flags = SF_STR_ALLOW_START ; | |||
153 | ||||
154 | /* | |||
155 | ** By default, add the peak chunk to floating point files. Default behaviour | |||
156 | ** can be switched off using sf_command (SFC_SET_PEAK_CHUNK, SF_FALSE). | |||
157 | */ | |||
158 | if (psf->file.mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)) | |||
159 | { if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL((void*)0)) | |||
160 | return SFE_MALLOC_FAILED ; | |||
161 | psf->peak_info->peak_loc = SF_PEAK_START ; | |||
162 | } ; | |||
163 | ||||
164 | if ((error = caf_write_header (psf, SF_FALSE)) != 0) | |||
165 | return error ; | |||
166 | ||||
167 | psf->write_header = caf_write_header ; | |||
168 | psf->set_chunk = caf_set_chunk ; | |||
169 | } ; | |||
170 | ||||
171 | psf->container_close = caf_close ; | |||
172 | psf->command = caf_command ; | |||
173 | ||||
174 | switch (subformat) | |||
175 | { case SF_FORMAT_PCM_S8 : | |||
176 | case SF_FORMAT_PCM_16 : | |||
177 | case SF_FORMAT_PCM_24 : | |||
178 | case SF_FORMAT_PCM_32 : | |||
179 | error = pcm_init (psf) ; | |||
180 | break ; | |||
181 | ||||
182 | case SF_FORMAT_ULAW : | |||
183 | error = ulaw_init (psf) ; | |||
184 | break ; | |||
185 | ||||
186 | case SF_FORMAT_ALAW : | |||
187 | error = alaw_init (psf) ; | |||
188 | break ; | |||
189 | ||||
190 | /* Lite remove start */ | |||
191 | case SF_FORMAT_FLOAT : | |||
192 | error = float32_init (psf) ; | |||
193 | break ; | |||
194 | ||||
195 | case SF_FORMAT_DOUBLE : | |||
196 | error = double64_init (psf) ; | |||
197 | break ; | |||
198 | ||||
199 | case SF_FORMAT_ALAC_16 : | |||
200 | case SF_FORMAT_ALAC_20 : | |||
201 | case SF_FORMAT_ALAC_24 : | |||
202 | case SF_FORMAT_ALAC_32 : | |||
203 | if (psf->file.mode == SFM_READ) | |||
204 | /* Only pass the ALAC_DECODER_INFO in read mode. */ | |||
205 | error = alac_init (psf, &pcaf->alac) ; | |||
206 | else | |||
207 | error = alac_init (psf, NULL((void*)0)) ; | |||
208 | break ; | |||
209 | ||||
210 | /* Lite remove end */ | |||
211 | ||||
212 | default : | |||
213 | return SFE_UNSUPPORTED_ENCODING ; | |||
214 | } ; | |||
215 | ||||
216 | return error ; | |||
217 | } /* caf_open */ | |||
218 | ||||
219 | static int | |||
220 | caf_close (SF_PRIVATE *psf) | |||
221 | { | |||
222 | if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) | |||
223 | caf_write_header (psf, SF_TRUE) ; | |||
224 | ||||
225 | return 0 ; | |||
226 | } /* caf_close */ | |||
227 | ||||
228 | static int | |||
229 | caf_command (SF_PRIVATE * psf, int command, void * UNUSED (data)UNUSED_data __attribute__ ((unused)), int UNUSED (datasize)UNUSED_datasize __attribute__ ((unused))) | |||
230 | { CAF_PRIVATE *pcaf ; | |||
231 | ||||
232 | if ((pcaf = psf->container_data) == NULL((void*)0)) | |||
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 | ||||
250 | static int | |||
251 | decode_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((uint32_t) (('a') | (('l') << 8) | (('a') << 16) | (((uint32_t) ('c')) << 24)))) | |||
257 | { CAF_PRIVATE *pcaf ; | |||
258 | ||||
259 | if ((pcaf = psf->container_data) != NULL((void*)0)) | |||
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((uint32_t) (('l') | (('p') << 8) | (('c') << 16) | (((uint32_t) ('m')) << 24))) && 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((uint32_t) (('l') | (('p') << 8) | (('c') << 16) | (((uint32_t) ('m')) << 24))) && (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((uint32_t) (('a') | (('l') << 8) | (('a') << 16) | (((uint32_t) ('w')) << 24))) && desc->bits_per_chan == 8) | |||
322 | { psf->bytewidth = 1 ; | |||
323 | return format | SF_FORMAT_ALAW ; | |||
324 | } ; | |||
325 | ||||
326 | if (desc->fmt_id == ulaw_MARKER((uint32_t) (('u') | (('l') << 8) | (('a') << 16) | (((uint32_t) ('w')) << 24))) && 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 | ||||
336 | static int | |||
337 | caf_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((void*)0)) | |||
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((uint32_t) (('c') | (('a') << 8) | (('f') << 16) | (((uint32_t) ('f')) << 24)))) | |||
355 | return SFE_CAF_NOT_CAF666 ; | |||
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)__builtin___snprintf_chk (ubuf.cbuf, sizeof (ubuf.cbuf), 2 - 1 , __builtin_object_size (ubuf.cbuf, 2 > 1), "%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((uint32_t) (('d') | (('e') << 8) | (('s') << 16) | (((uint32_t) ('c')) << 24)))) | |||
362 | return SFE_CAF_NO_DESC667 ; | |||
363 | ||||
364 | if (chunk_size < SIGNED_SIZEOF (DESC_CHUNK)((int) 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 = 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_CHANNELS256) | |||
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)((int) 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 (psf_ftell (psf) < psf->filelength) | |||
388 | { marker = 0 ; | |||
389 | chunk_size = 0 ; | |||
390 | ||||
391 | psf_binheader_readf (psf, "mE8", &marker, &chunk_size) ; | |||
392 | if (marker == 0) | |||
393 | { psf_log_printf (psf, "Have 0 marker.\n") ; | |||
394 | break ; | |||
395 | } ; | |||
396 | ||||
397 | psf_store_read_chunk_u32 (&psf->rchunks, marker, psf_ftell (psf), chunk_size) ; | |||
398 | ||||
399 | switch (marker) | |||
400 | { case peak_MARKER((uint32_t) (('p') | (('e') << 8) | (('a') << 16) | (((uint32_t) ('k')) << 24))) : | |||
401 | psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ; | |||
402 | if (chunk_size != CAF_PEAK_CHUNK_SIZE (psf->sf.channels)((int) (sizeof (int) + psf->sf.channels * (sizeof (float) + 8)))) | |||
403 | { psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ; | |||
404 | psf_log_printf (psf, "*** File PEAK chunk %D should be %d.\n", chunk_size, CAF_PEAK_CHUNK_SIZE (psf->sf.channels)((int) (sizeof (int) + psf->sf.channels * (sizeof (float) + 8)))) ; | |||
405 | return SFE_CAF_BAD_PEAK668 ; | |||
406 | } ; | |||
407 | ||||
408 | if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL((void*)0)) | |||
409 | return SFE_MALLOC_FAILED ; | |||
410 | ||||
411 | /* read in rest of PEAK chunk. */ | |||
412 | psf_binheader_readf (psf, "E4", & (psf->peak_info->edit_number)) ; | |||
413 | psf_log_printf (psf, " edit count : %d\n", psf->peak_info->edit_number) ; | |||
414 | ||||
415 | psf_log_printf (psf, " Ch Position Value\n") ; | |||
416 | for (k = 0 ; k < psf->sf.channels ; k++) | |||
417 | { sf_count_t position ; | |||
418 | float value ; | |||
419 | ||||
420 | psf_binheader_readf (psf, "Ef8", &value, &position) ; | |||
421 | psf->peak_info->peaks [k].value = value ; | |||
422 | psf->peak_info->peaks [k].position = position ; | |||
423 | ||||
424 | snprintf (ubuf.cbuf, sizeof (ubuf.cbuf), " %2d %-12" PRId64 " %g\n", k, position, value)__builtin___snprintf_chk (ubuf.cbuf, sizeof (ubuf.cbuf), 2 - 1 , __builtin_object_size (ubuf.cbuf, 2 > 1), " %2d %-12" "l" "d" " %g\n", k, position, value) ; | |||
425 | psf_log_printf (psf, ubuf.cbuf) ; | |||
426 | } ; | |||
427 | ||||
428 | psf->peak_info->peak_loc = SF_PEAK_START ; | |||
429 | break ; | |||
430 | ||||
431 | case chan_MARKER((uint32_t) (('c') | (('h') << 8) | (('a') << 16) | (((uint32_t) ('n')) << 24))) : | |||
432 | if (chunk_size < 12) | |||
433 | { psf_log_printf (psf, "%M : %D (should be >= 12)\n", marker, chunk_size) ; | |||
434 | psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ; | |||
435 | break ; | |||
436 | } | |||
437 | ||||
438 | psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ; | |||
439 | ||||
440 | if ((error = caf_read_chanmap (psf, chunk_size))) | |||
441 | return error ; | |||
442 | break ; | |||
443 | ||||
444 | case free_MARKER((uint32_t) (('f') | (('r') << 8) | (('e') << 16) | (((uint32_t) ('e')) << 24))) : | |||
445 | psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ; | |||
446 | psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ; | |||
447 | break ; | |||
448 | ||||
449 | case data_MARKER((uint32_t) (('d') | (('a') << 8) | (('t') << 16) | (((uint32_t) ('a')) << 24))) : | |||
450 | psf_binheader_readf (psf, "E4", &k) ; | |||
451 | psf_log_printf (psf, " edit : %u\n", k) ; | |||
452 | ||||
453 | if (chunk_size == -1) | |||
454 | { psf_log_printf (psf, "%M : -1\n") ; | |||
455 | chunk_size = psf->filelength - psf->headindex ; | |||
456 | } | |||
457 | else if (psf->filelength > 0 && psf->filelength < psf->headindex + chunk_size - 16) | |||
458 | psf_log_printf (psf, "%M : %D (should be %D)\n", marker, chunk_size, psf->filelength - psf->headindex - 8) ; | |||
459 | else | |||
460 | psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ; | |||
461 | ||||
462 | ||||
463 | psf->dataoffset = psf->headindex ; | |||
464 | ||||
465 | /* Subtract the 4 bytes of the 'edit' field above. */ | |||
466 | psf->datalength = chunk_size - 4 ; | |||
467 | ||||
468 | psf_binheader_readf (psf, "j", psf->datalength) ; | |||
469 | have_data = 1 ; | |||
470 | break ; | |||
471 | ||||
472 | case kuki_MARKER((uint32_t) (('k') | (('u') << 8) | (('k') << 16) | (((uint32_t) ('i')) << 24))) : | |||
473 | psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ; | |||
474 | pcaf->alac.kuki_offset = psf_ftell (psf) - 12 ; | |||
475 | psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ; | |||
476 | break ; | |||
477 | ||||
478 | case pakt_MARKER((uint32_t) (('p') | (('a') << 8) | (('k') << 16) | (((uint32_t) ('t')) << 24))) : | |||
479 | psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ; | |||
480 | ||||
481 | psf_binheader_readf (psf, "E8844", &pcaf->alac.packets, &pcaf->alac.valid_frames, | |||
482 | &pcaf->alac.priming_frames, &pcaf->alac.remainder_frames) ; | |||
483 | ||||
484 | psf_log_printf (psf, | |||
485 | " Packets : %D\n" | |||
486 | " Valid frames : %D\n" | |||
487 | " Priming frames : %d\n" | |||
488 | " Remainder frames : %d\n", | |||
489 | pcaf->alac.packets, pcaf->alac.valid_frames, pcaf->alac.priming_frames, | |||
490 | pcaf->alac.remainder_frames | |||
491 | ) ; | |||
492 | ||||
493 | if (pcaf->alac.packets == 0 && pcaf->alac.valid_frames == 0 | |||
494 | && pcaf->alac.priming_frames == 0 && pcaf->alac.remainder_frames == 0) | |||
495 | psf_log_printf (psf, "*** 'pakt' chunk header is all zero.\n") ; | |||
496 | ||||
497 | pcaf->alac.pakt_offset = psf_ftell (psf) - 12 ; | |||
498 | psf_binheader_readf (psf, "j", make_size_t (chunk_size) - 24) ; | |||
499 | break ; | |||
500 | ||||
501 | default : | |||
502 | psf_log_printf (psf, "%M : %D (skipped)\n", marker, chunk_size) ; | |||
503 | psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ; | |||
504 | break ; | |||
505 | } ; | |||
506 | ||||
507 | if (! psf->sf.seekable && have_data) | |||
508 | break ; | |||
509 | ||||
510 | if (psf_ftell (psf) >= psf->filelength - SIGNED_SIZEOF (chunk_size)((int) sizeof (chunk_size))) | |||
511 | { psf_log_printf (psf, "End\n") ; | |||
512 | break ; | |||
513 | } ; | |||
514 | } ; | |||
515 | ||||
516 | if (have_data == 0) | |||
517 | { psf_log_printf (psf, "**** Error, could not find 'data' chunk.\n") ; | |||
518 | return SFE_MALFORMED_FILE ; | |||
519 | } ; | |||
520 | ||||
521 | psf->endian = (desc.fmt_flags & 2) ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ; | |||
522 | ||||
523 | psf_fseek (psf, psf->dataoffset, SEEK_SET0) ; | |||
524 | ||||
525 | if ((psf->sf.format = decode_desc_chunk (psf, &desc)) == 0) | |||
526 | return SFE_UNSUPPORTED_ENCODING ; | |||
527 | ||||
528 | if (psf->bytewidth > 0) | |||
529 | psf->sf.frames = psf->datalength / psf->bytewidth ; | |||
530 | ||||
531 | return 0 ; | |||
532 | } /* caf_read_header */ | |||
533 | ||||
534 | /*------------------------------------------------------------------------------ | |||
535 | */ | |||
536 | ||||
537 | static int | |||
538 | caf_write_header (SF_PRIVATE *psf, int calc_length) | |||
539 | { BUF_UNION ubuf ; | |||
540 | CAF_PRIVATE *pcaf ; | |||
541 | DESC_CHUNK desc ; | |||
542 | sf_count_t current, free_len ; | |||
543 | uint32_t uk ; | |||
544 | int subformat, append_free_block = SF_TRUE ; | |||
545 | ||||
546 | if ((pcaf = psf->container_data) == NULL((void*)0)) | |||
547 | return SFE_INTERNAL ; | |||
548 | ||||
549 | memset (&desc, 0, sizeof (desc)) ; | |||
550 | ||||
551 | current = psf_ftell (psf) ; | |||
552 | ||||
553 | if (calc_length) | |||
554 | { psf->filelength = psf_get_filelen (psf) ; | |||
555 | ||||
556 | psf->datalength = psf->filelength - psf->dataoffset ; | |||
557 | ||||
558 | if (psf->dataend) | |||
559 | psf->datalength -= psf->filelength - psf->dataend ; | |||
560 | ||||
561 | if (psf->bytewidth > 0) | |||
562 | psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ; | |||
563 | } ; | |||
564 | ||||
565 | /* Reset the current header length to zero. */ | |||
566 | psf->header [0] = 0 ; | |||
567 | psf->headindex = 0 ; | |||
568 | psf_fseek (psf, 0, SEEK_SET0) ; | |||
569 | ||||
570 | /* 'caff' marker, version and flags. */ | |||
571 | psf_binheader_writef (psf, "Em22", caff_MARKER((uint32_t) (('c') | (('a') << 8) | (('f') << 16) | (((uint32_t) ('f')) << 24))), 1, 0) ; | |||
572 | ||||
573 | /* 'desc' marker and chunk size. */ | |||
574 | psf_binheader_writef (psf, "Em8", desc_MARKER((uint32_t) (('d') | (('e') << 8) | (('s') << 16) | (((uint32_t) ('c')) << 24))), (sf_count_t) (sizeof (DESC_CHUNK))) ; | |||
575 | ||||
576 | double64_be_write (1.0 * psf->sf.samplerate, ubuf.ucbuf) ; | |||
577 | psf_binheader_writef (psf, "b", ubuf.ucbuf, make_size_t (8)) ; | |||
578 | ||||
579 | subformat = SF_CODEC (psf->sf.format)((psf->sf.format) & SF_FORMAT_SUBMASK) ; | |||
580 | ||||
581 | psf->endian = SF_ENDIAN (psf->sf.format)((psf->sf.format) & SF_FORMAT_ENDMASK) ; | |||
582 | ||||
583 | if (CPU_IS_BIG_ENDIAN0 && (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU)) | |||
584 | psf->endian = SF_ENDIAN_BIG ; | |||
585 | else if (CPU_IS_LITTLE_ENDIAN1 && (psf->endian == SF_ENDIAN_LITTLE || psf->endian == SF_ENDIAN_CPU)) | |||
586 | psf->endian = SF_ENDIAN_LITTLE ; | |||
587 | ||||
588 | if (psf->endian == SF_ENDIAN_LITTLE) | |||
589 | desc.fmt_flags = 2 ; | |||
590 | else | |||
591 | psf->endian = SF_ENDIAN_BIG ; | |||
592 | ||||
593 | /* initial section (same for all, it appears) */ | |||
594 | switch (subformat) | |||
595 | { case SF_FORMAT_PCM_S8 : | |||
596 | desc.fmt_id = lpcm_MARKER((uint32_t) (('l') | (('p') << 8) | (('c') << 16) | (((uint32_t) ('m')) << 24))) ; | |||
597 | psf->bytewidth = 1 ; | |||
598 | desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; | |||
599 | desc.frames_per_packet = 1 ; | |||
600 | desc.channels_per_frame = psf->sf.channels ; | |||
601 | desc.bits_per_chan = 8 ; | |||
602 | break ; | |||
603 | ||||
604 | case SF_FORMAT_PCM_16 : | |||
605 | desc.fmt_id = lpcm_MARKER((uint32_t) (('l') | (('p') << 8) | (('c') << 16) | (((uint32_t) ('m')) << 24))) ; | |||
606 | psf->bytewidth = 2 ; | |||
607 | desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; | |||
608 | desc.frames_per_packet = 1 ; | |||
609 | desc.channels_per_frame = psf->sf.channels ; | |||
610 | desc.bits_per_chan = 16 ; | |||
611 | break ; | |||
612 | ||||
613 | case SF_FORMAT_PCM_24 : | |||
614 | psf->bytewidth = 3 ; | |||
615 | desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; | |||
616 | desc.frames_per_packet = 1 ; | |||
617 | desc.channels_per_frame = psf->sf.channels ; | |||
618 | desc.bits_per_chan = 24 ; | |||
619 | desc.fmt_id = lpcm_MARKER((uint32_t) (('l') | (('p') << 8) | (('c') << 16) | (((uint32_t) ('m')) << 24))) ; | |||
620 | break ; | |||
621 | ||||
622 | case SF_FORMAT_PCM_32 : | |||
623 | desc.fmt_id = lpcm_MARKER((uint32_t) (('l') | (('p') << 8) | (('c') << 16) | (((uint32_t) ('m')) << 24))) ; | |||
624 | psf->bytewidth = 4 ; | |||
625 | desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; | |||
626 | desc.frames_per_packet = 1 ; | |||
627 | desc.channels_per_frame = psf->sf.channels ; | |||
628 | desc.bits_per_chan = 32 ; | |||
629 | break ; | |||
630 | ||||
631 | case SF_FORMAT_FLOAT : | |||
632 | desc.fmt_id = lpcm_MARKER((uint32_t) (('l') | (('p') << 8) | (('c') << 16) | (((uint32_t) ('m')) << 24))) ; | |||
633 | desc.fmt_flags |= 1 ; | |||
634 | psf->bytewidth = 4 ; | |||
635 | desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; | |||
636 | desc.frames_per_packet = 1 ; | |||
637 | desc.channels_per_frame = psf->sf.channels ; | |||
638 | desc.bits_per_chan = 32 ; | |||
639 | break ; | |||
640 | ||||
641 | case SF_FORMAT_DOUBLE : | |||
642 | desc.fmt_id = lpcm_MARKER((uint32_t) (('l') | (('p') << 8) | (('c') << 16) | (((uint32_t) ('m')) << 24))) ; | |||
643 | desc.fmt_flags |= 1 ; | |||
644 | psf->bytewidth = 8 ; | |||
645 | desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; | |||
646 | desc.frames_per_packet = 1 ; | |||
647 | desc.channels_per_frame = psf->sf.channels ; | |||
648 | desc.bits_per_chan = 64 ; | |||
649 | break ; | |||
650 | ||||
651 | case SF_FORMAT_ALAW : | |||
652 | desc.fmt_id = alaw_MARKER((uint32_t) (('a') | (('l') << 8) | (('a') << 16) | (((uint32_t) ('w')) << 24))) ; | |||
653 | psf->bytewidth = 1 ; | |||
654 | desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; | |||
655 | desc.frames_per_packet = 1 ; | |||
656 | desc.channels_per_frame = psf->sf.channels ; | |||
657 | desc.bits_per_chan = 8 ; | |||
658 | break ; | |||
659 | ||||
660 | case SF_FORMAT_ULAW : | |||
661 | desc.fmt_id = ulaw_MARKER((uint32_t) (('u') | (('l') << 8) | (('a') << 16) | (((uint32_t) ('w')) << 24))) ; | |||
662 | psf->bytewidth = 1 ; | |||
663 | desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; | |||
664 | desc.frames_per_packet = 1 ; | |||
665 | desc.channels_per_frame = psf->sf.channels ; | |||
666 | desc.bits_per_chan = 8 ; | |||
667 | break ; | |||
668 | ||||
669 | case SF_FORMAT_ALAC_16 : | |||
670 | case SF_FORMAT_ALAC_20 : | |||
671 | case SF_FORMAT_ALAC_24 : | |||
672 | case SF_FORMAT_ALAC_32 : | |||
673 | desc.fmt_id = alac_MARKER((uint32_t) (('a') | (('l') << 8) | (('a') << 16) | (((uint32_t) ('c')) << 24))) ; | |||
674 | desc.pkt_bytes = psf->bytewidth * psf->sf.channels ; | |||
675 | desc.channels_per_frame = psf->sf.channels ; | |||
676 | alac_get_desc_chunk_items (subformat, &desc.fmt_flags, &desc.frames_per_packet) ; | |||
677 | append_free_block = SF_FALSE ; | |||
678 | break ; | |||
679 | ||||
680 | default : | |||
681 | return SFE_UNIMPLEMENTED ; | |||
682 | } ; | |||
683 | ||||
684 | psf_binheader_writef (psf, "mE44444", desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.frames_per_packet, desc.channels_per_frame, desc.bits_per_chan) ; | |||
685 | ||||
686 | #if 0 | |||
687 | if (psf->strings.flags & SF_STR_LOCATE_START) | |||
688 | caf_write_strings (psf, SF_STR_LOCATE_START) ; | |||
689 | #endif | |||
690 | ||||
691 | if (psf->peak_info != NULL((void*)0)) | |||
692 | { int k ; | |||
693 | psf_binheader_writef (psf, "Em84", peak_MARKER((uint32_t) (('p') | (('e') << 8) | (('a') << 16) | (((uint32_t) ('k')) << 24))), (sf_count_t) CAF_PEAK_CHUNK_SIZE (psf->sf.channels)((int) (sizeof (int) + psf->sf.channels * (sizeof (float) + 8))), psf->peak_info->edit_number) ; | |||
694 | for (k = 0 ; k < psf->sf.channels ; k++) | |||
695 | psf_binheader_writef (psf, "Ef8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ; | |||
696 | } ; | |||
697 | ||||
698 | if (psf->channel_map && pcaf->chanmap_tag) | |||
699 | psf_binheader_writef (psf, "Em8444", chan_MARKER((uint32_t) (('c') | (('h') << 8) | (('a') << 16) | (((uint32_t) ('n')) << 24))), (sf_count_t) 12, pcaf->chanmap_tag, 0, 0) ; | |||
700 | ||||
701 | /* Write custom headers. */ | |||
702 | for (uk = 0 ; uk < psf->wchunks.used ; uk++) | |||
703 | psf_binheader_writef (psf, "m44b", (int) psf->wchunks.chunks [uk].mark32, 0, psf->wchunks.chunks [uk].len, psf->wchunks.chunks [uk].data, make_size_t (psf->wchunks.chunks [uk].len)) ; | |||
704 | ||||
705 | if (append_free_block) | |||
706 | { /* Add free chunk so that the actual audio data starts at a multiple 0x1000. */ | |||
707 | free_len = 0x1000 - psf->headindex - 16 - 12 ; | |||
708 | while (free_len < 0) | |||
709 | free_len += 0x1000 ; | |||
710 | psf_binheader_writef (psf, "Em8z", free_MARKER((uint32_t) (('f') | (('r') << 8) | (('e') << 16) | (((uint32_t) ('e')) << 24))), free_len, (int) free_len) ; | |||
711 | } ; | |||
712 | ||||
713 | psf_binheader_writef (psf, "Em84", data_MARKER((uint32_t) (('d') | (('a') << 8) | (('t') << 16) | (((uint32_t) ('a')) << 24))), psf->datalength + 4, 0) ; | |||
714 | ||||
715 | psf_fwrite (psf->header, psf->headindex, 1, psf) ; | |||
716 | if (psf->error) | |||
717 | return psf->error ; | |||
718 | ||||
719 | psf->dataoffset = psf->headindex ; | |||
720 | if (current < psf->dataoffset) | |||
721 | psf_fseek (psf, psf->dataoffset, SEEK_SET0) ; | |||
722 | else if (current > 0) | |||
723 | psf_fseek (psf, current, SEEK_SET0) ; | |||
724 | ||||
725 | return psf->error ; | |||
726 | } /* caf_write_header */ | |||
727 | ||||
728 | static int | |||
729 | caf_read_chanmap (SF_PRIVATE * psf, sf_count_t chunk_size) | |||
730 | { const AIFF_CAF_CHANNEL_MAP * map_info ; | |||
731 | unsigned channel_bitmap, channel_decriptions, bytesread ; | |||
732 | int layout_tag ; | |||
733 | ||||
734 | bytesread = psf_binheader_readf (psf, "E444", &layout_tag, &channel_bitmap, &channel_decriptions) ; | |||
735 | ||||
736 | map_info = aiff_caf_of_channel_layout_tag (layout_tag) ; | |||
| ||||
737 | ||||
738 | psf_log_printf (psf, " Tag : %x\n", layout_tag) ; | |||
739 | if (map_info) | |||
740 | psf_log_printf (psf, " Layout : %s\n", map_info->name) ; | |||
741 | ||||
742 | if (bytesread < chunk_size) | |||
743 | psf_binheader_readf (psf, "j", chunk_size - bytesread) ; | |||
744 | ||||
745 | if (map_info->channel_map != NULL((void*)0)) | |||
| ||||
746 | { size_t chanmap_size = psf->sf.channels * sizeof (psf->channel_map [0]) ; | |||
747 | ||||
748 | free (psf->channel_map) ; | |||
749 | ||||
750 | if ((psf->channel_map = malloc (chanmap_size)) == NULL((void*)0)) | |||
751 | return SFE_MALLOC_FAILED ; | |||
752 | ||||
753 | memcpy (psf->channel_map, map_info->channel_map, chanmap_size) ; | |||
754 | } ; | |||
755 | ||||
756 | return 0 ; | |||
757 | } /* caf_read_chanmap */ | |||
758 | ||||
759 | /*============================================================================== | |||
760 | */ | |||
761 | ||||
762 | static int | |||
763 | caf_set_chunk (SF_PRIVATE *psf, const SF_CHUNK_INFO * chunk_info) | |||
764 | { return psf_save_write_chunk (&psf->wchunks, chunk_info) ; | |||
765 | } /* caf_set_chunk */ | |||
766 | ||||
767 | static SF_CHUNK_ITERATOR * | |||
768 | caf_next_chunk_iterator (SF_PRIVATE *psf, SF_CHUNK_ITERATOR * iterator) | |||
769 | { return psf_next_chunk_iterator (&psf->rchunks, iterator) ; | |||
770 | } /* caf_next_chunk_iterator */ | |||
771 | ||||
772 | static int | |||
773 | caf_get_chunk_size (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) | |||
774 | { int indx ; | |||
775 | ||||
776 | if ((indx = psf_find_read_chunk_iterator (&psf->rchunks, iterator)) < 0) | |||
777 | return SFE_UNKNOWN_CHUNK ; | |||
778 | ||||
779 | chunk_info->datalen = psf->rchunks.chunks [indx].len ; | |||
780 | ||||
781 | return SFE_NO_ERROR ; | |||
782 | } /* caf_get_chunk_size */ | |||
783 | ||||
784 | static int | |||
785 | caf_get_chunk_data (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) | |||
786 | { int indx ; | |||
787 | sf_count_t pos ; | |||
788 | ||||
789 | if ((indx = psf_find_read_chunk_iterator (&psf->rchunks, iterator)) < 0) | |||
790 | return SFE_UNKNOWN_CHUNK ; | |||
791 | ||||
792 | if (chunk_info->data == NULL((void*)0)) | |||
793 | return SFE_BAD_CHUNK_DATA_PTR ; | |||
794 | ||||
795 | chunk_info->id_size = psf->rchunks.chunks [indx].id_size ; | |||
796 | memcpy (chunk_info->id, psf->rchunks.chunks [indx].id, sizeof (chunk_info->id) / sizeof (*chunk_info->id)) ; | |||
797 | ||||
798 | pos = psf_ftell (psf) ; | |||
799 | psf_fseek (psf, psf->rchunks.chunks [indx].offset, SEEK_SET0) ; | |||
800 | psf_fread (chunk_info->data, SF_MIN (chunk_info->datalen, psf->rchunks.chunks [indx].len)({ typeof (chunk_info->datalen) sf_min_x2 = (chunk_info-> datalen) ; typeof (psf->rchunks.chunks [indx].len) sf_min_y2 = (psf->rchunks.chunks [indx].len) ; (void) (&sf_min_x2 == &sf_min_y2) ; sf_min_x2 < sf_min_y2 ? sf_min_x2 : sf_min_y2 ; }), 1, psf) ; | |||
801 | psf_fseek (psf, pos, SEEK_SET0) ; | |||
802 | ||||
803 | return SFE_NO_ERROR ; | |||
804 | } /* caf_get_chunk_data */ |