Coverage Report

Created: 2025-07-18 06:14

/src/libsndfile/src/paf.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
** Copyright (C) 1999-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 <fcntl.h>
24
#include <string.h>
25
#include <ctype.h>
26
#include <math.h>
27
28
#include "sndfile.h"
29
#include "sfendian.h"
30
#include "common.h"
31
32
/*------------------------------------------------------------------------------
33
** Macros to handle big/little endian issues.
34
*/
35
36
169
#define FAP_MARKER  (MAKE_MARKER ('f', 'a', 'p', ' '))
37
345
#define PAF_MARKER  (MAKE_MARKER (' ', 'p', 'a', 'f'))
38
39
/*------------------------------------------------------------------------------
40
** Other defines.
41
*/
42
43
700
#define PAF_HEADER_LENGTH       2048
44
45
6.77M
#define PAF24_SAMPLES_PER_BLOCK   10
46
3.67M
#define PAF24_BLOCK_SIZE      32
47
48
/*------------------------------------------------------------------------------
49
** Typedefs.
50
*/
51
52
typedef struct
53
{ int version ;
54
  int endianness ;
55
  int samplerate ;
56
  int format ;
57
  int channels ;
58
  int source ;
59
} PAF_FMT ;
60
61
typedef struct
62
{ int       max_blocks, channels, blocksize ;
63
  int       read_block, write_block, read_count, write_count ;
64
  sf_count_t    sample_count ;
65
  int       *samples ;
66
  int       *block ;
67
  int       data [] ; /* ISO C99 struct flexible array. */
68
} PAF24_PRIVATE ;
69
70
/*------------------------------------------------------------------------------
71
** Private static functions.
72
*/
73
74
static int paf24_init (SF_PRIVATE *psf) ;
75
76
static int  paf_read_header (SF_PRIVATE *psf) ;
77
static int  paf_write_header (SF_PRIVATE *psf, int calc_length) ;
78
79
static sf_count_t paf24_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
80
static sf_count_t paf24_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
81
static sf_count_t paf24_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
82
static sf_count_t paf24_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
83
84
static sf_count_t paf24_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
85
static sf_count_t paf24_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
86
static sf_count_t paf24_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
87
static sf_count_t paf24_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
88
89
static sf_count_t paf24_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
90
91
enum
92
{ PAF_PCM_16 = 0,
93
  PAF_PCM_24 = 1,
94
  PAF_PCM_S8 = 2
95
} ;
96
97
/*------------------------------------------------------------------------------
98
** Public function.
99
*/
100
101
int
102
paf_open  (SF_PRIVATE *psf)
103
350
{ int   subformat, error, endian ;
104
105
350
  psf->dataoffset = PAF_HEADER_LENGTH ;
106
107
350
  if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
108
350
  { if ((error = paf_read_header (psf)))
109
66
      return error ;
110
350
    } ;
111
112
284
  subformat = SF_CODEC (psf->sf.format) ;
113
114
284
  if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
115
0
  { if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_PAF)
116
0
      return  SFE_BAD_OPEN_FORMAT ;
117
118
0
    endian = SF_ENDIAN (psf->sf.format) ;
119
120
    /* PAF is by default big endian. */
121
0
    psf->endian = SF_ENDIAN_BIG ;
122
123
0
    if (endian == SF_ENDIAN_LITTLE || (CPU_IS_LITTLE_ENDIAN && (endian == SF_ENDIAN_CPU)))
124
0
      psf->endian = SF_ENDIAN_LITTLE ;
125
126
0
    if ((error = paf_write_header (psf, SF_FALSE)))
127
0
      return error ;
128
129
0
    psf->write_header = paf_write_header ;
130
284
    } ;
131
132
284
  switch (subformat)
133
284
  { case SF_FORMAT_PCM_S8 :
134
4
          psf->bytewidth = 1 ;
135
4
          error = pcm_init (psf) ;
136
4
          break ;
137
138
9
    case SF_FORMAT_PCM_16 :
139
9
          psf->bytewidth = 2 ;
140
9
          error = pcm_init (psf) ;
141
9
          break ;
142
143
271
    case SF_FORMAT_PCM_24 :
144
          /* No bytewidth because of whacky 24 bit encoding. */
145
271
          error = paf24_init (psf) ;
146
271
          break ;
147
148
0
    default : return SFE_PAF_UNKNOWN_FORMAT ;
149
284
    } ;
150
151
284
  return error ;
152
284
} /* paf_open */
153
154
/*------------------------------------------------------------------------------
155
*/
156
157
static int
158
paf_read_header (SF_PRIVATE *psf)
159
350
{ PAF_FMT   paf_fmt ;
160
350
  int     marker ;
161
162
350
  if (psf->filelength < PAF_HEADER_LENGTH)
163
5
    return SFE_PAF_SHORT_HEADER ;
164
165
345
  memset (&paf_fmt, 0, sizeof (paf_fmt)) ;
166
345
  psf_binheader_readf (psf, "pm", 0, &marker) ;
167
168
345
  psf_log_printf (psf, "Signature   : '%M'\n", marker) ;
169
170
345
  if (marker == PAF_MARKER)
171
176
  { psf_binheader_readf (psf, "E444444", &(paf_fmt.version), &(paf_fmt.endianness),
172
176
      &(paf_fmt.samplerate), &(paf_fmt.format), &(paf_fmt.channels), &(paf_fmt.source)) ;
173
176
    }
174
169
  else if (marker == FAP_MARKER)
175
169
  { psf_binheader_readf (psf, "e444444", &(paf_fmt.version), &(paf_fmt.endianness),
176
169
      &(paf_fmt.samplerate), &(paf_fmt.format), &(paf_fmt.channels), &(paf_fmt.source)) ;
177
169
    }
178
0
  else
179
0
    return SFE_PAF_NO_MARKER ;
180
181
345
  psf_log_printf (psf, "Version     : %d\n", paf_fmt.version) ;
182
183
345
  if (paf_fmt.version != 0)
184
2
  { psf_log_printf (psf, "*** Bad version number. should be zero.\n") ;
185
2
    return SFE_PAF_VERSION ;
186
343
    } ;
187
188
343
  psf_log_printf (psf, "Sample Rate : %d\n", paf_fmt.samplerate) ;
189
343
  psf_log_printf (psf, "Channels    : %d\n", paf_fmt.channels) ;
190
191
343
  psf_log_printf (psf, "Endianness  : %d => ", paf_fmt.endianness) ;
192
343
  if (paf_fmt.endianness)
193
217
  { psf_log_printf (psf, "Little\n", paf_fmt.endianness) ;
194
217
    psf->endian = SF_ENDIAN_LITTLE ;
195
217
    }
196
126
  else
197
126
  { psf_log_printf (psf, "Big\n", paf_fmt.endianness) ;
198
126
    psf->endian = SF_ENDIAN_BIG ;
199
126
    } ;
200
201
343
  if (paf_fmt.channels < 1 || paf_fmt.channels > SF_MAX_CHANNELS)
202
43
    return SFE_PAF_BAD_CHANNELS ;
203
204
300
  psf->datalength = psf->filelength - psf->dataoffset ;
205
206
300
  psf_binheader_readf (psf, "p", (int) psf->dataoffset) ;
207
208
300
  psf->sf.samplerate  = paf_fmt.samplerate ;
209
300
  psf->sf.channels  = paf_fmt.channels ;
210
211
  /* Only fill in type major. */
212
300
  psf->sf.format = SF_FORMAT_PAF ;
213
214
300
  psf_log_printf (psf, "Format      : %d => ", paf_fmt.format) ;
215
216
  /* PAF is by default big endian. */
217
300
  psf->sf.format |= paf_fmt.endianness ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ;
218
219
300
  switch (paf_fmt.format)
220
300
  { case PAF_PCM_S8 :
221
4
          psf_log_printf (psf, "8 bit linear PCM\n") ;
222
4
          psf->bytewidth = 1 ;
223
224
4
          psf->sf.format |= SF_FORMAT_PCM_S8 ;
225
226
4
          psf->blockwidth = psf->bytewidth * psf->sf.channels ;
227
4
          psf->sf.frames = psf->datalength / psf->blockwidth ;
228
4
          break ;
229
230
9
    case PAF_PCM_16 :
231
9
          psf_log_printf (psf, "16 bit linear PCM\n") ;
232
9
          psf->bytewidth = 2 ;
233
234
9
          psf->sf.format |= SF_FORMAT_PCM_16 ;
235
236
9
          psf->blockwidth = psf->bytewidth * psf->sf.channels ;
237
9
          psf->sf.frames = psf->datalength / psf->blockwidth ;
238
9
          break ;
239
240
271
    case PAF_PCM_24 :
241
271
          psf_log_printf (psf, "24 bit linear PCM\n") ;
242
271
          psf->bytewidth = 3 ;
243
244
271
          psf->sf.format |= SF_FORMAT_PCM_24 ;
245
246
271
          psf->blockwidth = 0 ;
247
271
          psf->sf.frames = PAF24_SAMPLES_PER_BLOCK * psf->datalength /
248
271
                      (PAF24_BLOCK_SIZE * psf->sf.channels) ;
249
271
          break ;
250
251
16
    default : psf_log_printf (psf, "Unknown\n") ;
252
16
          return SFE_PAF_UNKNOWN_FORMAT ;
253
0
          break ;
254
300
    } ;
255
256
284
  psf_log_printf (psf, "Source      : %d => ", paf_fmt.source) ;
257
258
284
  switch (paf_fmt.source)
259
284
  { case 1 : psf_log_printf (psf, "Analog Recording\n") ;
260
12
          break ;
261
18
    case 2 : psf_log_printf (psf, "Digital Transfer\n") ;
262
18
          break ;
263
6
    case 3 : psf_log_printf (psf, "Multi-track Mixdown\n") ;
264
6
          break ;
265
16
    case 5 : psf_log_printf (psf, "Audio Resulting From DSP Processing\n") ;
266
16
          break ;
267
232
    default : psf_log_printf (psf, "Unknown\n") ;
268
232
          break ;
269
284
    } ;
270
271
284
  return 0 ;
272
284
} /* paf_read_header */
273
274
static int
275
paf_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
276
0
{ int     paf_format ;
277
278
  /* PAF header already written so no need to re-write. */
279
0
  if (psf_ftell (psf) >= PAF_HEADER_LENGTH)
280
0
    return 0 ;
281
282
0
  psf->dataoffset = PAF_HEADER_LENGTH ;
283
284
0
  switch (SF_CODEC (psf->sf.format))
285
0
  { case SF_FORMAT_PCM_S8 :
286
0
          paf_format = PAF_PCM_S8 ;
287
0
          break ;
288
289
0
    case SF_FORMAT_PCM_16 :
290
0
          paf_format = PAF_PCM_16 ;
291
0
          break ;
292
293
0
    case SF_FORMAT_PCM_24 :
294
0
          paf_format = PAF_PCM_24 ;
295
0
          break ;
296
297
0
    default : return SFE_PAF_UNKNOWN_FORMAT ;
298
0
    } ;
299
300
  /* Reset the current header length to zero. */
301
0
  psf->header.ptr [0] = 0 ;
302
0
  psf->header.indx = 0 ;
303
304
0
  if (psf->endian == SF_ENDIAN_BIG)
305
0
  { /* Marker, version, endianness, samplerate */
306
0
    psf_binheader_writef (psf, "Em444", BHWm (PAF_MARKER), BHW4 (0), BHW4 (0), BHW4 (psf->sf.samplerate)) ;
307
    /* format, channels, source */
308
0
    psf_binheader_writef (psf, "E444", BHW4 (paf_format), BHW4 (psf->sf.channels), BHW4 (0)) ;
309
0
    }
310
0
  else if (psf->endian == SF_ENDIAN_LITTLE)
311
0
  { /* Marker, version, endianness, samplerate */
312
0
    psf_binheader_writef (psf, "em444", BHWm (FAP_MARKER), BHW4 (0), BHW4 (1), BHW4 (psf->sf.samplerate)) ;
313
    /* format, channels, source */
314
0
    psf_binheader_writef (psf, "e444", BHW4 (paf_format), BHW4 (psf->sf.channels), BHW4 (0)) ;
315
0
    } ;
316
317
  /* Zero fill to dataoffset. */
318
0
  psf_binheader_writef (psf, "z", BHWz ((size_t) (psf->dataoffset - psf->header.indx))) ;
319
320
0
  psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ;
321
322
0
  return psf->error ;
323
0
} /* paf_write_header */
324
325
/*===============================================================================
326
**  24 bit PAF files have a really weird encoding.
327
**  For a mono file, 10 samples (each being 3 bytes) are packed into a 32 byte
328
**  block. The 8 ints in this 32 byte block are then endian swapped (as ints)
329
**  if necessary before being written to disk.
330
**  For a stereo file, blocks of 10 samples from the same channel are encoded
331
**  into 32 bytes as for the mono case. The 32 byte blocks are then interleaved
332
**  on disk.
333
**  Reading has to reverse the above process :-).
334
**  Weird!!!
335
**
336
**  The code below attempts to gain efficiency while maintaining readability.
337
*/
338
339
static int paf24_read_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24) ;
340
static int paf24_write_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24) ;
341
static int paf24_close (SF_PRIVATE *psf) ;
342
343
344
static int
345
paf24_init (SF_PRIVATE *psf)
346
271
{ PAF24_PRIVATE *ppaf24 ;
347
271
  int paf24size ;
348
349
271
  paf24size = sizeof (PAF24_PRIVATE) + psf->sf.channels *
350
271
          (PAF24_BLOCK_SIZE + PAF24_SAMPLES_PER_BLOCK * sizeof (int)) ;
351
352
  /*
353
  **  Not exactly sure why this needs to be here but the tests
354
  **  fail without it.
355
  */
356
271
  psf->last_op = 0 ;
357
358
271
  if (! (psf->codec_data = calloc (1, paf24size)))
359
0
    return SFE_MALLOC_FAILED ;
360
361
271
  ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
362
363
271
  ppaf24->channels  = psf->sf.channels ;
364
271
  ppaf24->samples   = ppaf24->data ;
365
271
  ppaf24->block   = ppaf24->data + PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ;
366
367
271
  ppaf24->blocksize = PAF24_BLOCK_SIZE * ppaf24->channels ;
368
369
271
  if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
370
271
  { paf24_read_block (psf, ppaf24) ;  /* Read first block. */
371
372
271
    psf->read_short   = paf24_read_s ;
373
271
    psf->read_int   = paf24_read_i ;
374
271
    psf->read_float   = paf24_read_f ;
375
271
    psf->read_double  = paf24_read_d ;
376
271
    } ;
377
378
271
  if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
379
0
  { psf->write_short  = paf24_write_s ;
380
0
    psf->write_int    = paf24_write_i ;
381
0
    psf->write_float  = paf24_write_f ;
382
0
    psf->write_double = paf24_write_d ;
383
0
    } ;
384
385
271
  psf->seek = paf24_seek ;
386
271
  psf->container_close  = paf24_close ;
387
388
271
  psf->filelength = psf_get_filelen (psf) ;
389
271
  psf->datalength = psf->filelength - psf->dataoffset ;
390
391
271
  if (psf->datalength % PAF24_BLOCK_SIZE)
392
227
  { if (psf->file.mode == SFM_READ)
393
227
      psf_log_printf (psf, "*** Warning : file seems to be truncated.\n") ;
394
227
    ppaf24->max_blocks = psf->datalength / ppaf24->blocksize + 1 ;
395
227
    }
396
44
  else
397
44
    ppaf24->max_blocks = psf->datalength / ppaf24->blocksize ;
398
399
271
  ppaf24->read_block = 0 ;
400
271
  if (psf->file.mode == SFM_RDWR)
401
0
    ppaf24->write_block = ppaf24->max_blocks ;
402
271
  else
403
271
    ppaf24->write_block = 0 ;
404
405
271
  psf->sf.frames = PAF24_SAMPLES_PER_BLOCK * ppaf24->max_blocks ;
406
271
  ppaf24->sample_count = psf->sf.frames ;
407
408
271
  return 0 ;
409
271
} /* paf24_init */
410
411
static sf_count_t
412
paf24_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
413
248
{ PAF24_PRIVATE *ppaf24 ;
414
248
  int       newblock, newsample ;
415
416
248
  if (psf->codec_data == NULL)
417
0
  { psf->error = SFE_INTERNAL ;
418
0
    return PSF_SEEK_ERROR ;
419
248
    } ;
420
421
248
  ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
422
423
248
  if (mode == SFM_READ && ppaf24->write_count > 0)
424
0
    paf24_write_block (psf, ppaf24) ;
425
426
248
  newblock  = offset / PAF24_SAMPLES_PER_BLOCK ;
427
248
  newsample = offset % PAF24_SAMPLES_PER_BLOCK ;
428
429
248
  switch (mode)
430
248
  { case SFM_READ :
431
248
        if (psf->last_op == SFM_WRITE && ppaf24->write_count)
432
0
          paf24_write_block (psf, ppaf24) ;
433
434
248
        psf_fseek (psf, psf->dataoffset + newblock * ppaf24->blocksize, SEEK_SET) ;
435
248
        ppaf24->read_block = newblock ;
436
248
        paf24_read_block (psf, ppaf24) ;
437
248
        ppaf24->read_count = newsample ;
438
248
        break ;
439
440
0
    case SFM_WRITE :
441
0
        if (offset > ppaf24->sample_count)
442
0
        { psf->error = SFE_BAD_SEEK ;
443
0
          return PSF_SEEK_ERROR ;
444
0
          } ;
445
446
0
        if (psf->last_op == SFM_WRITE && ppaf24->write_count)
447
0
          paf24_write_block (psf, ppaf24) ;
448
449
0
        psf_fseek (psf, psf->dataoffset + newblock * ppaf24->blocksize, SEEK_SET) ;
450
0
        ppaf24->write_block = newblock ;
451
0
        paf24_read_block (psf, ppaf24) ;
452
0
        ppaf24->write_count = newsample ;
453
0
        break ;
454
455
0
    default :
456
0
        psf->error = SFE_BAD_SEEK ;
457
0
        return PSF_SEEK_ERROR ;
458
248
    } ;
459
460
248
  return newblock * PAF24_SAMPLES_PER_BLOCK + newsample ;
461
248
} /* paf24_seek */
462
463
static int
464
paf24_close (SF_PRIVATE *psf)
465
271
{ PAF24_PRIVATE *ppaf24 ;
466
467
271
  if (psf->codec_data == NULL)
468
0
    return 0 ;
469
470
271
  ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
471
472
271
  if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
473
0
  { if (ppaf24->write_count > 0)
474
0
      paf24_write_block (psf, ppaf24) ;
475
0
    } ;
476
477
271
  return 0 ;
478
271
} /* paf24_close */
479
480
/*---------------------------------------------------------------------------
481
*/
482
static int
483
paf24_read_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24)
484
324k
{ int       k, channel ;
485
324k
  unsigned char *cptr ;
486
487
324k
  ppaf24->read_block ++ ;
488
324k
  ppaf24->read_count = 0 ;
489
490
324k
  if (ppaf24->read_block * PAF24_SAMPLES_PER_BLOCK > ppaf24->sample_count)
491
271
  { memset (ppaf24->samples, 0, PAF24_SAMPLES_PER_BLOCK * ppaf24->channels) ;
492
271
    return 1 ;
493
323k
    } ;
494
495
  /* Read the block. */
496
323k
  if ((k = (int) psf_fread (ppaf24->block, 1, ppaf24->blocksize, psf)) != ppaf24->blocksize)
497
226
    psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, ppaf24->blocksize) ;
498
499
  /* Do endian swapping if necessary. */
500
323k
  if ((CPU_IS_BIG_ENDIAN && psf->endian == SF_ENDIAN_LITTLE) || (CPU_IS_LITTLE_ENDIAN && psf->endian == SF_ENDIAN_BIG))
501
184k
    endswap_int_array (ppaf24->block, 8 * ppaf24->channels) ;
502
503
  /* Unpack block. */
504
4.00M
  for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++)
505
3.67M
  { channel = k % ppaf24->channels ;
506
3.67M
    cptr = ((unsigned char *) ppaf24->block) + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ;
507
3.67M
    ppaf24->samples [k] = (cptr [0] << 8) | (cptr [1] << 16) | (((unsigned) cptr [2]) << 24) ;
508
3.67M
    } ;
509
510
323k
  return 1 ;
511
324k
} /* paf24_read_block */
512
513
static int
514
paf24_read (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24, int *ptr, int len)
515
550k
{ int count, total = 0 ;
516
517
1.36M
  while (total < len)
518
819k
  { if (ppaf24->read_block * PAF24_SAMPLES_PER_BLOCK >= ppaf24->sample_count)
519
4.59k
    { memset (&(ptr [total]), 0, (len - total) * sizeof (int)) ;
520
4.59k
      return total ;
521
814k
      } ;
522
523
814k
    if (ppaf24->read_count >= PAF24_SAMPLES_PER_BLOCK)
524
323k
      paf24_read_block (psf, ppaf24) ;
525
526
814k
    count = (PAF24_SAMPLES_PER_BLOCK - ppaf24->read_count) * ppaf24->channels ;
527
814k
    count = (len - total > count) ? count : len - total ;
528
529
814k
    memcpy (&(ptr [total]), &(ppaf24->samples [ppaf24->read_count * ppaf24->channels]), count * sizeof (int)) ;
530
814k
    total += count ;
531
814k
    ppaf24->read_count += count / ppaf24->channels ;
532
814k
    } ;
533
534
545k
  return total ;
535
550k
} /* paf24_read */
536
537
static sf_count_t
538
paf24_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
539
79
{ BUF_UNION   ubuf ;
540
79
  PAF24_PRIVATE   *ppaf24 ;
541
79
  int       *iptr ;
542
79
  int       k, bufferlen, readcount, count ;
543
79
  sf_count_t    total = 0 ;
544
545
79
  if (psf->codec_data == NULL)
546
0
    return 0 ;
547
79
  ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
548
549
79
  iptr = ubuf.ibuf ;
550
79
  bufferlen = ARRAY_LEN (ubuf.ibuf) ;
551
2.89k
  while (len > 0)
552
2.82k
  { readcount = (len >= bufferlen) ? bufferlen : (int) len ;
553
2.82k
    count = paf24_read (psf, ppaf24, iptr, readcount) ;
554
5.67M
    for (k = 0 ; k < readcount ; k++)
555
5.67M
      ptr [total + k] = iptr [k] >> 16 ;
556
2.82k
    total += count ;
557
2.82k
    len -= readcount ;
558
2.82k
    } ;
559
79
  return total ;
560
79
} /* paf24_read_s */
561
562
static sf_count_t
563
paf24_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
564
41
{ PAF24_PRIVATE *ppaf24 ;
565
41
  int       total ;
566
567
41
  if (psf->codec_data == NULL)
568
0
    return 0 ;
569
41
  ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
570
571
41
  total = paf24_read (psf, ppaf24, ptr, len) ;
572
573
41
  return total ;
574
41
} /* paf24_read_i */
575
576
static sf_count_t
577
paf24_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
578
544k
{ BUF_UNION   ubuf ;
579
544k
  PAF24_PRIVATE   *ppaf24 ;
580
544k
  int       *iptr ;
581
544k
  int       k, bufferlen, readcount, count ;
582
544k
  sf_count_t    total = 0 ;
583
544k
  float     normfact ;
584
585
544k
  if (psf->codec_data == NULL)
586
0
    return 0 ;
587
544k
  ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
588
589
544k
  normfact = (psf->norm_float == SF_TRUE) ? (1.0 / 0x80000000) : (1.0 / 0x100) ;
590
591
544k
  iptr = ubuf.ibuf ;
592
544k
  bufferlen = ARRAY_LEN (ubuf.ibuf) ;
593
1.08M
  while (len > 0)
594
544k
  { readcount = (len >= bufferlen) ? bufferlen : (int) len ;
595
544k
    count = paf24_read (psf, ppaf24, iptr, readcount) ;
596
1.09M
    for (k = 0 ; k < readcount ; k++)
597
548k
      ptr [total + k] = normfact * iptr [k] ;
598
544k
    total += count ;
599
544k
    len -= readcount ;
600
544k
    } ;
601
544k
  return total ;
602
544k
} /* paf24_read_f */
603
604
static sf_count_t
605
paf24_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
606
81
{ BUF_UNION   ubuf ;
607
81
  PAF24_PRIVATE   *ppaf24 ;
608
81
  int       *iptr ;
609
81
  int       k, bufferlen, readcount, count ;
610
81
  sf_count_t    total = 0 ;
611
81
  double      normfact ;
612
613
81
  if (psf->codec_data == NULL)
614
0
    return 0 ;
615
81
  ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
616
617
81
  normfact = (psf->norm_double == SF_TRUE) ? (1.0 / 0x80000000) : (1.0 / 0x100) ;
618
619
81
  iptr = ubuf.ibuf ;
620
81
  bufferlen = ARRAY_LEN (ubuf.ibuf) ;
621
3.11k
  while (len > 0)
622
3.02k
  { readcount = (len >= bufferlen) ? bufferlen : (int) len ;
623
3.02k
    count = paf24_read (psf, ppaf24, iptr, readcount) ;
624
6.09M
    for (k = 0 ; k < readcount ; k++)
625
6.09M
      ptr [total + k] = normfact * iptr [k] ;
626
3.02k
    total += count ;
627
3.02k
    len -= readcount ;
628
3.02k
    } ;
629
81
  return total ;
630
81
} /* paf24_read_d */
631
632
/*---------------------------------------------------------------------------
633
*/
634
635
static int
636
paf24_write_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24)
637
0
{ int       k, nextsample, channel ;
638
0
  unsigned char *cptr ;
639
640
  /* First pack block. */
641
642
0
  if (CPU_IS_LITTLE_ENDIAN)
643
0
  { for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++)
644
0
    { channel = k % ppaf24->channels ;
645
0
      cptr = ((unsigned char *) ppaf24->block) + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ;
646
0
      nextsample = ppaf24->samples [k] >> 8 ;
647
0
      cptr [0] = nextsample ;
648
0
      cptr [1] = nextsample >> 8 ;
649
0
      cptr [2] = nextsample >> 16 ;
650
0
      } ;
651
652
    /* Do endian swapping if necessary. */
653
0
    if (psf->endian == SF_ENDIAN_BIG)
654
0
      endswap_int_array (ppaf24->block, 8 * ppaf24->channels) ;
655
0
    }
656
0
  else if (CPU_IS_BIG_ENDIAN)
657
0
  { /* This is correct. */
658
0
    for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++)
659
0
    { channel = k % ppaf24->channels ;
660
0
      cptr = ((unsigned char *) ppaf24->block) + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ;
661
0
      nextsample = ppaf24->samples [k] >> 8 ;
662
0
      cptr [0] = nextsample ;
663
0
      cptr [1] = nextsample >> 8 ;
664
0
      cptr [2] = nextsample >> 16 ;
665
0
      } ;
666
0
    if (psf->endian == SF_ENDIAN_LITTLE)
667
0
      endswap_int_array (ppaf24->block, 8 * ppaf24->channels) ;
668
0
    } ;
669
670
  /* Write block to disk. */
671
0
  if ((k = (int) psf_fwrite (ppaf24->block, 1, ppaf24->blocksize, psf)) != ppaf24->blocksize)
672
0
    psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, ppaf24->blocksize) ;
673
674
0
  if (ppaf24->sample_count < ppaf24->write_block * PAF24_SAMPLES_PER_BLOCK + ppaf24->write_count)
675
0
    ppaf24->sample_count = ppaf24->write_block * PAF24_SAMPLES_PER_BLOCK + ppaf24->write_count ;
676
677
0
  if (ppaf24->write_count == PAF24_SAMPLES_PER_BLOCK)
678
0
  { ppaf24->write_block ++ ;
679
0
    ppaf24->write_count = 0 ;
680
0
    } ;
681
682
0
  return 1 ;
683
0
} /* paf24_write_block */
684
685
static int
686
paf24_write (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24, const int *ptr, int len)
687
0
{ int   count, total = 0 ;
688
689
0
  while (total < len)
690
0
  { count = (PAF24_SAMPLES_PER_BLOCK - ppaf24->write_count) * ppaf24->channels ;
691
692
0
    if (count > len - total)
693
0
      count = len - total ;
694
695
0
    memcpy (&(ppaf24->samples [ppaf24->write_count * ppaf24->channels]), &(ptr [total]), count * sizeof (int)) ;
696
0
    total += count ;
697
0
    ppaf24->write_count += count / ppaf24->channels ;
698
699
0
    if (ppaf24->write_count >= PAF24_SAMPLES_PER_BLOCK)
700
0
      paf24_write_block (psf, ppaf24) ;
701
0
    } ;
702
703
0
  return total ;
704
0
} /* paf24_write */
705
706
static sf_count_t
707
paf24_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
708
0
{ BUF_UNION   ubuf ;
709
0
  PAF24_PRIVATE   *ppaf24 ;
710
0
  int       *iptr ;
711
0
  int       k, bufferlen, writecount = 0, count ;
712
0
  sf_count_t    total = 0 ;
713
714
0
  if (psf->codec_data == NULL)
715
0
    return 0 ;
716
0
  ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
717
718
0
  iptr = ubuf.ibuf ;
719
0
  bufferlen = ARRAY_LEN (ubuf.ibuf) ;
720
0
  while (len > 0)
721
0
  { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
722
0
    for (k = 0 ; k < writecount ; k++)
723
0
      iptr [k] = ptr [total + k] << 16 ;
724
0
    count = paf24_write (psf, ppaf24, iptr, writecount) ;
725
0
    total += count ;
726
0
    len -= writecount ;
727
0
    if (count != writecount)
728
0
      break ;
729
0
    } ;
730
0
  return total ;
731
0
} /* paf24_write_s */
732
733
static sf_count_t
734
paf24_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
735
0
{ PAF24_PRIVATE   *ppaf24 ;
736
0
  int       writecount, count ;
737
0
  sf_count_t    total = 0 ;
738
739
0
  if (psf->codec_data == NULL)
740
0
    return 0 ;
741
0
  ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
742
743
0
  while (len > 0)
744
0
  { writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
745
746
0
    count = paf24_write (psf, ppaf24, ptr, writecount) ;
747
748
0
    total += count ;
749
0
    len -= count ;
750
0
    if (count != writecount)
751
0
      break ;
752
0
    } ;
753
754
0
  return total ;
755
0
} /* paf24_write_i */
756
757
static sf_count_t
758
paf24_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
759
0
{ BUF_UNION   ubuf ;
760
0
  PAF24_PRIVATE   *ppaf24 ;
761
0
  int       *iptr ;
762
0
  int       k, bufferlen, writecount = 0, count ;
763
0
  sf_count_t    total = 0 ;
764
0
  float     normfact ;
765
766
0
  if (psf->codec_data == NULL)
767
0
    return 0 ;
768
0
  ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
769
770
0
  normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : (1.0 / 0x100) ;
771
772
0
  iptr = ubuf.ibuf ;
773
0
  bufferlen = ARRAY_LEN (ubuf.ibuf) ;
774
0
  while (len > 0)
775
0
  { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
776
0
    for (k = 0 ; k < writecount ; k++)
777
0
      iptr [k] = psf_lrintf (normfact * ptr [total + k]) ;
778
0
    count = paf24_write (psf, ppaf24, iptr, writecount) ;
779
0
    total += count ;
780
0
    len -= writecount ;
781
0
    if (count != writecount)
782
0
      break ;
783
0
    } ;
784
785
0
  return total ;
786
0
} /* paf24_write_f */
787
788
static sf_count_t
789
paf24_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
790
0
{ BUF_UNION   ubuf ;
791
0
  PAF24_PRIVATE   *ppaf24 ;
792
0
  int       *iptr ;
793
0
  int       k, bufferlen, writecount = 0, count ;
794
0
  sf_count_t    total = 0 ;
795
0
  double      normfact ;
796
797
0
  if (psf->codec_data == NULL)
798
0
    return 0 ;
799
0
  ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
800
801
0
  normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : (1.0 / 0x100) ;
802
803
0
  iptr = ubuf.ibuf ;
804
0
  bufferlen = ARRAY_LEN (ubuf.ibuf) ;
805
0
  while (len > 0)
806
0
  { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
807
0
    for (k = 0 ; k < writecount ; k++)
808
0
      iptr [k] = psf_lrint (normfact * ptr [total+k]) ;
809
0
    count = paf24_write (psf, ppaf24, iptr, writecount) ;
810
0
    total += count ;
811
0
    len -= writecount ;
812
0
    if (count != writecount)
813
0
      break ;
814
0
    } ;
815
816
0
  return total ;
817
0
} /* paf24_write_d */
818