1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
$NetBSD: patch-ad,v 1.2 2009/12/01 10:44:02 drochner Exp $
--- libaudiofile/wave.c.orig 2004-03-06 07:39:23.000000000 +0100
+++ libaudiofile/wave.c
@@ -199,11 +199,13 @@ static status ParseFormat (AFfilehandle
case WAVE_FORMAT_ADPCM:
{
u_int16_t bitsPerSample, extraByteCount,
- samplesPerBlock, numCoefficients;
+ samplesPerBlock, numCoefficients,
+ framesPerBlock;
int i;
AUpvlist pv;
long l;
void *v;
+ int minBlockLength;
if (track->f.channelCount != 1 &&
track->f.channelCount != 2)
@@ -216,11 +218,33 @@ static status ParseFormat (AFfilehandle
af_fread(&bitsPerSample, 1, 2, fp);
bitsPerSample = LENDIAN_TO_HOST_INT16(bitsPerSample);
+ if (bitsPerSample != 4)
+ {
+ _af_error(AF_BAD_WIDTH,
+ "bad sample width of %hd bits",
+ bitsPerSample);
+ return AF_FAIL;
+ }
+
af_fread(&extraByteCount, 1, 2, fp);
extraByteCount = LENDIAN_TO_HOST_INT16(extraByteCount);
- af_fread(&samplesPerBlock, 1, 2, fp);
- samplesPerBlock = LENDIAN_TO_HOST_INT16(samplesPerBlock);
+ af_fread(&framesPerBlock, 1, 2, fp);
+ framesPerBlock = LENDIAN_TO_HOST_INT16(framesPerBlock);
+
+ minBlockLength = 7 * channelCount; /* header */
+ if (framesPerBlock > 2)
+ minBlockLength += ( ( framesPerBlock - 2 ) * channelCount + 1) / 2;
+
+ if (blockAlign < minBlockLength)
+ {
+ _af_error(AF_BAD_FRAMECNT,
+ "blockAlign %hd too small for %hd samplesPerBlock",
+ blockAlign, samplesPerBlock);
+ return AF_FAIL;
+ }
+
+ samplesPerBlock = framesPerBlock *channelCount;
af_fread(&numCoefficients, 1, 2, fp);
numCoefficients = LENDIAN_TO_HOST_INT16(numCoefficients);
@@ -242,6 +266,7 @@ static status ParseFormat (AFfilehandle
wave->msadpcmCoefficients[i][1] = a1;
}
+
track->f.sampleWidth = 16;
track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
track->f.compressionType = AF_COMPRESSION_MS_ADPCM;
@@ -277,18 +302,44 @@ static status ParseFormat (AFfilehandle
{
AUpvlist pv;
long l;
+ int minBlockLength;
u_int16_t bitsPerSample, extraByteCount,
- samplesPerBlock;
+ samplesPerBlock, framesPerBlock;
af_fread(&bitsPerSample, 1, 2, fp);
bitsPerSample = LENDIAN_TO_HOST_INT16(bitsPerSample);
+ if (bitsPerSample != 4)
+ {
+ _af_error(AF_BAD_WIDTH,
+ "bad sample width of %hd bits",
+ bitsPerSample);
+ return AF_FAIL;
+ }
+
af_fread(&extraByteCount, 1, 2, fp);
extraByteCount = LENDIAN_TO_HOST_INT16(extraByteCount);
- af_fread(&samplesPerBlock, 1, 2, fp);
- samplesPerBlock = LENDIAN_TO_HOST_INT16(samplesPerBlock);
+ af_fread(&framesPerBlock, 1, 2, fp);
+ framesPerBlock = LENDIAN_TO_HOST_INT16(framesPerBlock);
+ samplesPerBlock = framesPerBlock * channelCount;
+
+ /* per channel, ima has blocks of len 4, the 1st has 1st sample, the others
+ * up to 8 samples per block,
+ * so number of later blocks is (nsamp-1 + 7)/8, total blocks/chan is
+ * (nsamp-1+7)/8 + 1 = (nsamp+14)/8
+ */
+
+ minBlockLength = ( framesPerBlock + 14 )/8 * 4 * channelCount;
+
+ if (blockAlign < minBlockLength)
+ {
+ _af_error(AF_BAD_FRAMECNT,
+ "blockAlign %hd too small for %hd samplesPerBlock",
+ blockAlign, samplesPerBlock);
+ return AF_FAIL;
+ }
track->f.sampleWidth = 16;
track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
|