Coverage Report

Created: 2026-04-12 06:26

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