Bug Summary

File:libs/libsndfile/src/ima_adpcm.c
Location:line 455, column 10
Description:Array subscript is undefined

Annotated Source Code

1/*
2** Copyright (C) 1999-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 <math.h>
25
26#include "sndfile.h"
27#include "sfendian.h"
28#include "common.h"
29
30typedef struct IMA_ADPCM_PRIVATE_tag
31{ int (*decode_block) (SF_PRIVATE *psf, struct IMA_ADPCM_PRIVATE_tag *pima) ;
32 int (*encode_block) (SF_PRIVATE *psf, struct IMA_ADPCM_PRIVATE_tag *pima) ;
33
34 int channels, blocksize, samplesperblock, blocks ;
35 int blockcount, samplecount ;
36 int previous [2] ;
37 int stepindx [2] ;
38 unsigned char *block ;
39 short *samples ;
40 short data [] ; /* ISO C99 struct flexible array. */
41} IMA_ADPCM_PRIVATE ;
42
43/*============================================================================================
44** Predefined IMA ADPCM data.
45*/
46
47static int ima_indx_adjust [16] =
48{ -1, -1, -1, -1, /* +0 - +3, decrease the step size */
49 +2, +4, +6, +8, /* +4 - +7, increase the step size */
50 -1, -1, -1, -1, /* -0 - -3, decrease the step size */
51 +2, +4, +6, +8, /* -4 - -7, increase the step size */
52} ;
53
54static int ima_step_size [89] =
55{ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
56 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230,
57 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
58 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
59 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,
60 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
61 32767
62} ;
63
64static int ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;
65static int ima_writer_init (SF_PRIVATE *psf, int blockalign) ;
66
67static int ima_read_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, short *ptr, int len) ;
68static int ima_write_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, const short *ptr, int len) ;
69
70static sf_count_t ima_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
71static sf_count_t ima_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
72static sf_count_t ima_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
73static sf_count_t ima_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
74
75static sf_count_t ima_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
76static sf_count_t ima_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
77static sf_count_t ima_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
78static sf_count_t ima_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
79
80static sf_count_t ima_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
81
82static int ima_close (SF_PRIVATE *psf) ;
83
84static int wav_w64_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
85static int wav_w64_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
86
87/*-static int aiff_ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;-*/
88static int aiff_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
89static int aiff_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
90
91
92static inline int
93clamp_ima_step_index (int indx)
94{ if (indx < 0)
95 return 0 ;
96 if (indx >= ARRAY_LEN (ima_step_size)((int) (sizeof (ima_step_size) / sizeof ((ima_step_size) [0])
))
)
97 return ARRAY_LEN (ima_step_size)((int) (sizeof (ima_step_size) / sizeof ((ima_step_size) [0])
))
- 1 ;
98
99 return indx ;
100} /* clamp_ima_step_index */
101
102/*============================================================================================
103** IMA ADPCM Reader initialisation function.
104*/
105
106int
107wav_w64_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
108{ int error ;
109
110 if (psf->codec_data != NULL((void*)0))
111 { psf_log_printf (psf, "*** psf->codec_data is not NULL.\n") ;
112 return SFE_INTERNAL ;
113 } ;
114
115 if (psf->file.mode == SFM_RDWR)
116 return SFE_BAD_MODE_RW ;
117
118 if (psf->file.mode == SFM_READ)
119 if ((error = ima_reader_init (psf, blockalign, samplesperblock)))
120 return error ;
121
122 if (psf->file.mode == SFM_WRITE)
123 if ((error = ima_writer_init (psf, blockalign)))
124 return error ;
125
126 psf->codec_close = ima_close ;
127 psf->seek = ima_seek ;
128
129 return 0 ;
130} /* wav_w64_ima_init */
131
132int
133aiff_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
134{ int error ;
135
136 if (psf->file.mode == SFM_RDWR)
137 return SFE_BAD_MODE_RW ;
138
139 if (psf->file.mode == SFM_READ)
140 if ((error = ima_reader_init (psf, blockalign, samplesperblock)))
141 return error ;
142
143 if (psf->file.mode == SFM_WRITE)
144 if ((error = ima_writer_init (psf, blockalign)))
145 return error ;
146
147 psf->codec_close = ima_close ;
148
149 return 0 ;
150} /* aiff_ima_init */
151
152static int
153ima_close (SF_PRIVATE *psf)
154{ IMA_ADPCM_PRIVATE *pima ;
155
156 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
157
158 if (psf->file.mode == SFM_WRITE)
159 { /* If a block has been partially assembled, write it out
160 ** as the final block.
161 */
162 if (pima->samplecount && pima->samplecount < pima->samplesperblock)
163 pima->encode_block (psf, pima) ;
164
165 psf->sf.frames = pima->samplesperblock * pima->blockcount / psf->sf.channels ;
166 } ;
167
168 return 0 ;
169} /* ima_close */
170
171/*============================================================================================
172** IMA ADPCM Read Functions.
173*/
174
175static int
176ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
177{ IMA_ADPCM_PRIVATE *pima ;
178 int pimasize, count ;
179
180 if (psf->file.mode != SFM_READ)
181 return SFE_BAD_MODE_RW ;
182
183 pimasize = sizeof (IMA_ADPCM_PRIVATE) + blockalign * psf->sf.channels + 3 * psf->sf.channels * samplesperblock ;
184
185 if (! (pima = calloc (1, pimasize)))
186 return SFE_MALLOC_FAILED ;
187
188 psf->codec_data = (void*) pima ;
189
190 pima->samples = pima->data ;
191 pima->block = (unsigned char*) (pima->data + samplesperblock * psf->sf.channels) ;
192
193 pima->channels = psf->sf.channels ;
194 pima->blocksize = blockalign ;
195 pima->samplesperblock = samplesperblock ;
196
197 psf->filelength = psf_get_filelen (psf) ;
198 psf->datalength = (psf->dataend) ? psf->dataend - psf->dataoffset :
199 psf->filelength - psf->dataoffset ;
200
201 if (pima->blocksize == 0)
202 { psf_log_printf (psf, "*** Error : pima->blocksize should not be zero.\n") ;
203 return SFE_INTERNAL ;
204 } ;
205
206 if (psf->datalength % pima->blocksize)
207 pima->blocks = psf->datalength / pima->blocksize + 1 ;
208 else
209 pima->blocks = psf->datalength / pima->blocksize ;
210
211 switch (SF_CONTAINER (psf->sf.format)((psf->sf.format) & SF_FORMAT_TYPEMASK))
212 { case SF_FORMAT_WAV :
213 case SF_FORMAT_W64 :
214 count = 2 * (pima->blocksize - 4 * pima->channels) / pima->channels + 1 ;
215
216 if (pima->samplesperblock != count)
217 { psf_log_printf (psf, "*** Error : samplesperblock should be %d.\n", count) ;
218 return SFE_INTERNAL ;
219 } ;
220
221 pima->decode_block = wav_w64_ima_decode_block ;
222
223 psf->sf.frames = pima->samplesperblock * pima->blocks ;
224 break ;
225
226 case SF_FORMAT_AIFF :
227 psf_log_printf (psf, "still need to check block count\n") ;
228 pima->decode_block = aiff_ima_decode_block ;
229 psf->sf.frames = pima->samplesperblock * pima->blocks / pima->channels ;
230 break ;
231
232 default :
233 psf_log_printf (psf, "ima_reader_init: bad psf->sf.format\n") ;
234 return SFE_INTERNAL ;
235 } ;
236
237 pima->decode_block (psf, pima) ; /* Read first block. */
238
239 psf->read_short = ima_read_s ;
240 psf->read_int = ima_read_i ;
241 psf->read_float = ima_read_f ;
242 psf->read_double = ima_read_d ;
243
244 return 0 ;
245} /* ima_reader_init */
246
247static int
248aiff_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
249{ unsigned char *blockdata ;
250 int chan, k, diff, bytecode, predictor ;
251 short step, stepindx, *sampledata ;
252
253static int count = 0 ;
254count ++ ;
255
256 pima->blockcount += pima->channels ;
257 pima->samplecount = 0 ;
258
259 if (pima->blockcount > pima->blocks)
260 { memset (pima->samples, 0, pima->samplesperblock * pima->channels * sizeof (short)) ;
261 return 1 ;
262 } ;
263
264 if ((k = psf_fread (pima->block, 1, pima->blocksize * pima->channels, psf)) != pima->blocksize * pima->channels)
265 psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pima->blocksize) ;
266
267 /* Read and check the block header. */
268 for (chan = 0 ; chan < pima->channels ; chan++)
269 { blockdata = pima->block + chan * 34 ;
270 sampledata = pima->samples + chan ;
271
272 predictor = (blockdata [0] << 8) | (blockdata [1] & 0x80) ;
273
274 stepindx = blockdata [1] & 0x7F ;
275 stepindx = clamp_ima_step_index (stepindx) ;
276
277 /*
278 ** Pull apart the packed 4 bit samples and store them in their
279 ** correct sample positions.
280 */
281 for (k = 0 ; k < pima->blocksize - 2 ; k++)
282 { bytecode = blockdata [k + 2] ;
283 sampledata [pima->channels * (2 * k + 0)] = bytecode & 0xF ;
284 sampledata [pima->channels * (2 * k + 1)] = (bytecode >> 4) & 0xF ;
285 } ;
286
287 /* Decode the encoded 4 bit samples. */
288 for (k = 0 ; k < pima->samplesperblock ; k ++)
289 { step = ima_step_size [stepindx] ;
290
291 bytecode = pima->samples [pima->channels * k + chan] ;
292
293 stepindx += ima_indx_adjust [bytecode] ;
294 stepindx = clamp_ima_step_index (stepindx) ;
295
296 diff = step >> 3 ;
297 if (bytecode & 1) diff += step >> 2 ;
298 if (bytecode & 2) diff += step >> 1 ;
299 if (bytecode & 4) diff += step ;
300 if (bytecode & 8) diff = -diff ;
301
302 predictor += diff ;
303 if (predictor < -32768)
304 predictor = -32768 ;
305 else if (predictor > 32767)
306 predictor = 32767 ;
307
308 pima->samples [pima->channels * k + chan] = predictor ;
309 } ;
310 } ;
311
312 return 1 ;
313} /* aiff_ima_decode_block */
314
315static int
316aiff_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
317{ int chan, k, step, diff, vpdiff, blockindx, indx ;
318 short bytecode, mask ;
319
320 /* Encode the block header. */
321 for (chan = 0 ; chan < pima->channels ; chan ++)
322 { blockindx = chan * pima->blocksize ;
323
324 pima->block [blockindx] = (pima->samples [chan] >> 8) & 0xFF ;
325 pima->block [blockindx + 1] = (pima->samples [chan] & 0x80) + (pima->stepindx [chan] & 0x7F) ;
326
327 pima->previous [chan] = pima->samples [chan] ;
328 } ;
329
330 /* Encode second and later samples for every block as a 4 bit value. */
331 for (k = pima->channels ; k < (pima->samplesperblock * pima->channels) ; k ++)
332 { chan = (pima->channels > 1) ? (k % 2) : 0 ;
333
334 diff = pima->samples [k] - pima->previous [chan] ;
335
336 bytecode = 0 ;
337 step = ima_step_size [pima->stepindx [chan]] ;
338 vpdiff = step >> 3 ;
339 if (diff < 0)
340 { bytecode = 8 ;
341 diff = -diff ;
342 } ;
343 mask = 4 ;
344 while (mask)
345 { if (diff >= step)
346 { bytecode |= mask ;
347 diff -= step ;
348 vpdiff += step ;
349 } ;
350 step >>= 1 ;
351 mask >>= 1 ;
352 } ;
353
354 if (bytecode & 8)
355 pima->previous [chan] -= vpdiff ;
356 else
357 pima->previous [chan] += vpdiff ;
358
359 if (pima->previous [chan] > 32767)
360 pima->previous [chan] = 32767 ;
361 else if (pima->previous [chan] < -32768)
362 pima->previous [chan] = -32768 ;
363
364 pima->stepindx [chan] += ima_indx_adjust [bytecode] ;
365
366 pima->stepindx [chan] = clamp_ima_step_index (pima->stepindx [chan]) ;
367 pima->samples [k] = bytecode ;
368 } ;
369
370 /* Pack the 4 bit encoded samples. */
371
372 for (chan = 0 ; chan < pima->channels ; chan ++)
373 { for (indx = pima->channels ; indx < pima->channels * pima->samplesperblock ; indx += 2 * pima->channels)
374 { blockindx = chan * pima->blocksize + 2 + indx / 2 ;
375
376 pima->block [blockindx] = pima->samples [indx] & 0x0F ;
377 pima->block [blockindx] |= (pima->samples [indx + chan] << 4) & 0xF0 ;
378 } ;
379 } ;
380
381 /* Write the block to disk. */
382
383 if ((k = psf_fwrite (pima->block, 1, pima->channels * pima->blocksize, psf)) != pima->channels * pima->blocksize)
384 psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pima->channels * pima->blocksize) ;
385
386 memset (pima->samples, 0, pima->channels * pima->samplesperblock * sizeof (short)) ;
387 pima->samplecount = 0 ;
388 pima->blockcount ++ ;
389
390 return 1 ;
391} /* aiff_ima_encode_block */
392
393static int
394wav_w64_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
395{ int chan, k, predictor, blockindx, indx, indxstart, diff ;
396 short step, bytecode, stepindx [2] ;
397
398 pima->blockcount ++ ;
399 pima->samplecount = 0 ;
400
401 if (pima->blockcount > pima->blocks)
1
Taking false branch
402 { memset (pima->samples, 0, pima->samplesperblock * pima->channels * sizeof (short)) ;
403 return 1 ;
404 } ;
405
406 if ((k = psf_fread (pima->block, 1, pima->blocksize, psf)) != pima->blocksize)
2
Taking false branch
407 psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pima->blocksize) ;
408
409 /* Read and check the block header. */
410
411 for (chan = 0 ; chan < pima->channels ; chan++)
3
Loop condition is false. Execution continues on line 431
412 { predictor = pima->block [chan*4] | (pima->block [chan*4+1] << 8) ;
413 if (predictor & 0x8000)
414 predictor -= 0x10000 ;
415
416 stepindx [chan] = pima->block [chan*4+2] ;
417 stepindx [chan] = clamp_ima_step_index (stepindx [chan]) ;
418
419
420 if (pima->block [chan*4+3] != 0)
421 psf_log_printf (psf, "IMA ADPCM synchronisation error.\n") ;
422
423 pima->samples [chan] = predictor ;
424 } ;
425
426 /*
427 ** Pull apart the packed 4 bit samples and store them in their
428 ** correct sample positions.
429 */
430
431 blockindx = 4 * pima->channels ;
432
433 indxstart = pima->channels ;
434 while (blockindx < pima->blocksize)
4
Loop condition is false. Execution continues on line 450
435 { for (chan = 0 ; chan < pima->channels ; chan++)
436 { indx = indxstart + chan ;
437 for (k = 0 ; k < 4 ; k++)
438 { bytecode = pima->block [blockindx++] ;
439 pima->samples [indx] = bytecode & 0x0F ;
440 indx += pima->channels ;
441 pima->samples [indx] = (bytecode >> 4) & 0x0F ;
442 indx += pima->channels ;
443 } ;
444 } ;
445 indxstart += 8 * pima->channels ;
446 } ;
447
448 /* Decode the encoded 4 bit samples. */
449
450 for (k = pima->channels ; k < (pima->samplesperblock * pima->channels) ; k ++)
5
Loop condition is true. Entering loop body
451 { chan = (pima->channels > 1) ? (k % 2) : 0 ;
6
'?' condition is false
452
453 bytecode = pima->samples [k] & 0xF ;
454
455 step = ima_step_size [stepindx [chan]] ;
7
Array subscript is undefined
456 predictor = pima->samples [k - pima->channels] ;
457
458 diff = step >> 3 ;
459 if (bytecode & 1)
460 diff += step >> 2 ;
461 if (bytecode & 2)
462 diff += step >> 1 ;
463 if (bytecode & 4)
464 diff += step ;
465 if (bytecode & 8)
466 diff = -diff ;
467
468 predictor += diff ;
469
470 if (predictor > 32767)
471 predictor = 32767 ;
472 else if (predictor < -32768)
473 predictor = -32768 ;
474
475 stepindx [chan] += ima_indx_adjust [bytecode] ;
476 stepindx [chan] = clamp_ima_step_index (stepindx [chan]) ;
477
478 pima->samples [k] = predictor ;
479 } ;
480
481 return 1 ;
482} /* wav_w64_ima_decode_block */
483
484static int
485wav_w64_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
486{ int chan, k, step, diff, vpdiff, blockindx, indx, indxstart ;
487 short bytecode, mask ;
488
489 /* Encode the block header. */
490 for (chan = 0 ; chan < pima->channels ; chan++)
491 { pima->block [chan*4] = pima->samples [chan] & 0xFF ;
492 pima->block [chan*4+1] = (pima->samples [chan] >> 8) & 0xFF ;
493
494 pima->block [chan*4+2] = pima->stepindx [chan] ;
495 pima->block [chan*4+3] = 0 ;
496
497 pima->previous [chan] = pima->samples [chan] ;
498 } ;
499
500 /* Encode the samples as 4 bit. */
501
502 for (k = pima->channels ; k < (pima->samplesperblock * pima->channels) ; k ++)
503 { chan = (pima->channels > 1) ? (k % 2) : 0 ;
504
505 diff = pima->samples [k] - pima->previous [chan] ;
506
507 bytecode = 0 ;
508 step = ima_step_size [pima->stepindx [chan]] ;
509 vpdiff = step >> 3 ;
510 if (diff < 0)
511 { bytecode = 8 ;
512 diff = -diff ;
513 } ;
514 mask = 4 ;
515 while (mask)
516 { if (diff >= step)
517 { bytecode |= mask ;
518 diff -= step ;
519 vpdiff += step ;
520 } ;
521 step >>= 1 ;
522 mask >>= 1 ;
523 } ;
524
525 if (bytecode & 8)
526 pima->previous [chan] -= vpdiff ;
527 else
528 pima->previous [chan] += vpdiff ;
529
530 if (pima->previous [chan] > 32767)
531 pima->previous [chan] = 32767 ;
532 else if (pima->previous [chan] < -32768)
533 pima->previous [chan] = -32768 ;
534
535 pima->stepindx [chan] += ima_indx_adjust [bytecode] ;
536 pima->stepindx [chan] = clamp_ima_step_index (pima->stepindx [chan]) ;
537
538 pima->samples [k] = bytecode ;
539 } ;
540
541 /* Pack the 4 bit encoded samples. */
542
543 blockindx = 4 * pima->channels ;
544
545 indxstart = pima->channels ;
546 while (blockindx < pima->blocksize)
547 { for (chan = 0 ; chan < pima->channels ; chan++)
548 { indx = indxstart + chan ;
549 for (k = 0 ; k < 4 ; k++)
550 { pima->block [blockindx] = pima->samples [indx] & 0x0F ;
551 indx += pima->channels ;
552 pima->block [blockindx] |= (pima->samples [indx] << 4) & 0xF0 ;
553 indx += pima->channels ;
554 blockindx ++ ;
555 } ;
556 } ;
557 indxstart += 8 * pima->channels ;
558 } ;
559
560 /* Write the block to disk. */
561
562 if ((k = psf_fwrite (pima->block, 1, pima->blocksize, psf)) != pima->blocksize)
563 psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pima->blocksize) ;
564
565 memset (pima->samples, 0, pima->samplesperblock * sizeof (short)) ;
566 pima->samplecount = 0 ;
567 pima->blockcount ++ ;
568
569 return 1 ;
570} /* wav_w64_ima_encode_block */
571
572static int
573ima_read_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, short *ptr, int len)
574{ int count, total = 0, indx = 0 ;
575
576 while (indx < len)
577 { if (pima->blockcount >= pima->blocks && pima->samplecount >= pima->samplesperblock)
578 { memset (&(ptr [indx]), 0, (size_t) ((len - indx) * sizeof (short))) ;
579 return total ;
580 } ;
581
582 if (pima->samplecount >= pima->samplesperblock)
583 pima->decode_block (psf, pima) ;
584
585 count = (pima->samplesperblock - pima->samplecount) * pima->channels ;
586 count = (len - indx > count) ? count : len - indx ;
587
588 memcpy (&(ptr [indx]), &(pima->samples [pima->samplecount * pima->channels]), count * sizeof (short)) ;
589 indx += count ;
590 pima->samplecount += count / pima->channels ;
591 total = indx ;
592 } ;
593
594 return total ;
595} /* ima_read_block */
596
597static sf_count_t
598ima_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
599{ IMA_ADPCM_PRIVATE *pima ;
600 int readcount, count ;
601 sf_count_t total = 0 ;
602
603 if (! psf->codec_data)
604 return 0 ;
605 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
606
607 while (len > 0)
608 { readcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
609
610 count = ima_read_block (psf, pima, ptr, readcount) ;
611
612 total += count ;
613 len -= count ;
614 if (count != readcount)
615 break ;
616 } ;
617
618 return total ;
619} /* ima_read_s */
620
621static sf_count_t
622ima_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
623{ IMA_ADPCM_PRIVATE *pima ;
624 BUF_UNION ubuf ;
625 short *sptr ;
626 int k, bufferlen, readcount, count ;
627 sf_count_t total = 0 ;
628
629 if (! psf->codec_data)
630 return 0 ;
631 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
632
633 sptr = ubuf.sbuf ;
634 bufferlen = ARRAY_LEN (ubuf.sbuf)((int) (sizeof (ubuf.sbuf) / sizeof ((ubuf.sbuf) [0]))) ;
635 while (len > 0)
636 { readcount = (len >= bufferlen) ? bufferlen : (int) len ;
637 count = ima_read_block (psf, pima, sptr, readcount) ;
638 for (k = 0 ; k < readcount ; k++)
639 ptr [total + k] = ((int) sptr [k]) << 16 ;
640 total += count ;
641 len -= readcount ;
642 if (count != readcount)
643 break ;
644 } ;
645
646 return total ;
647} /* ima_read_i */
648
649static sf_count_t
650ima_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
651{ IMA_ADPCM_PRIVATE *pima ;
652 BUF_UNION ubuf ;
653 short *sptr ;
654 int k, bufferlen, readcount, count ;
655 sf_count_t total = 0 ;
656 float normfact ;
657
658 if (! psf->codec_data)
659 return 0 ;
660 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
661
662 normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
663
664 sptr = ubuf.sbuf ;
665 bufferlen = ARRAY_LEN (ubuf.sbuf)((int) (sizeof (ubuf.sbuf) / sizeof ((ubuf.sbuf) [0]))) ;
666 while (len > 0)
667 { readcount = (len >= bufferlen) ? bufferlen : (int) len ;
668 count = ima_read_block (psf, pima, sptr, readcount) ;
669 for (k = 0 ; k < readcount ; k++)
670 ptr [total + k] = normfact * (float) (sptr [k]) ;
671 total += count ;
672 len -= readcount ;
673 if (count != readcount)
674 break ;
675 } ;
676
677 return total ;
678} /* ima_read_f */
679
680static sf_count_t
681ima_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
682{ IMA_ADPCM_PRIVATE *pima ;
683 BUF_UNION ubuf ;
684 short *sptr ;
685 int k, bufferlen, readcount, count ;
686 sf_count_t total = 0 ;
687 double normfact ;
688
689 if (! psf->codec_data)
690 return 0 ;
691 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
692
693 normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
694
695 sptr = ubuf.sbuf ;
696 bufferlen = ARRAY_LEN (ubuf.sbuf)((int) (sizeof (ubuf.sbuf) / sizeof ((ubuf.sbuf) [0]))) ;
697 while (len > 0)
698 { readcount = (len >= bufferlen) ? bufferlen : (int) len ;
699 count = ima_read_block (psf, pima, sptr, readcount) ;
700 for (k = 0 ; k < readcount ; k++)
701 ptr [total + k] = normfact * (double) (sptr [k]) ;
702 total += count ;
703 len -= readcount ;
704 if (count != readcount)
705 break ;
706 } ;
707
708 return total ;
709} /* ima_read_d */
710
711static sf_count_t
712ima_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
713{ IMA_ADPCM_PRIVATE *pima ;
714 int newblock, newsample ;
715
716 if (! psf->codec_data)
717 return 0 ;
718 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
719
720 if (psf->datalength < 0 || psf->dataoffset < 0)
721 { psf->error = SFE_BAD_SEEK ;
722 return PSF_SEEK_ERROR((sf_count_t) -1) ;
723 } ;
724
725 if (offset == 0)
726 { psf_fseek (psf, psf->dataoffset, SEEK_SET0) ;
727 pima->blockcount = 0 ;
728 pima->decode_block (psf, pima) ;
729 pima->samplecount = 0 ;
730 return 0 ;
731 } ;
732
733 if (offset < 0 || offset > pima->blocks * pima->samplesperblock)
734 { psf->error = SFE_BAD_SEEK ;
735 return PSF_SEEK_ERROR((sf_count_t) -1) ;
736 } ;
737
738 newblock = offset / pima->samplesperblock ;
739 newsample = offset % pima->samplesperblock ;
740
741 if (mode == SFM_READ)
742 { psf_fseek (psf, psf->dataoffset + newblock * pima->blocksize, SEEK_SET0) ;
743 pima->blockcount = newblock ;
744 pima->decode_block (psf, pima) ;
745 pima->samplecount = newsample ;
746 }
747 else
748 { /* What to do about write??? */
749 psf->error = SFE_BAD_SEEK ;
750 return PSF_SEEK_ERROR((sf_count_t) -1) ;
751 } ;
752
753 return newblock * pima->samplesperblock + newsample ;
754} /* ima_seek */
755
756/*==========================================================================================
757** IMA ADPCM Write Functions.
758*/
759
760static int
761ima_writer_init (SF_PRIVATE *psf, int blockalign)
762{ IMA_ADPCM_PRIVATE *pima ;
763 int samplesperblock ;
764 unsigned int pimasize ;
765
766 if (psf->file.mode != SFM_WRITE)
767 return SFE_BAD_MODE_RW ;
768
769 samplesperblock = 2 * (blockalign - 4 * psf->sf.channels) / psf->sf.channels + 1 ;
770
771 pimasize = sizeof (IMA_ADPCM_PRIVATE) + blockalign + 3 * psf->sf.channels * samplesperblock ;
772
773 if ((pima = calloc (1, pimasize)) == NULL((void*)0))
774 return SFE_MALLOC_FAILED ;
775
776 psf->codec_data = (void*) pima ;
777
778 pima->channels = psf->sf.channels ;
779 pima->blocksize = blockalign ;
780 pima->samplesperblock = samplesperblock ;
781
782 pima->block = (unsigned char*) pima->data ;
783 pima->samples = (short*) (pima->data + blockalign) ;
784
785 pima->samplecount = 0 ;
786
787 switch (SF_CONTAINER (psf->sf.format)((psf->sf.format) & SF_FORMAT_TYPEMASK))
788 { case SF_FORMAT_WAV :
789 case SF_FORMAT_W64 :
790 pima->encode_block = wav_w64_ima_encode_block ;
791 break ;
792
793 case SF_FORMAT_AIFF :
794 pima->encode_block = aiff_ima_encode_block ;
795 break ;
796
797 default :
798 psf_log_printf (psf, "ima_reader_init: bad psf->sf.format\n") ;
799 return SFE_INTERNAL ;
800 } ;
801
802 psf->write_short = ima_write_s ;
803 psf->write_int = ima_write_i ;
804 psf->write_float = ima_write_f ;
805 psf->write_double = ima_write_d ;
806
807 return 0 ;
808} /* ima_writer_init */
809
810/*==========================================================================================
811*/
812
813static int
814ima_write_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, const short *ptr, int len)
815{ int count, total = 0, indx = 0 ;
816
817 while (indx < len)
818 { count = (pima->samplesperblock - pima->samplecount) * pima->channels ;
819
820 if (count > len - indx)
821 count = len - indx ;
822
823 memcpy (&(pima->samples [pima->samplecount * pima->channels]), &(ptr [total]), count * sizeof (short)) ;
824 indx += count ;
825 pima->samplecount += count / pima->channels ;
826 total = indx ;
827
828 if (pima->samplecount >= pima->samplesperblock)
829 pima->encode_block (psf, pima) ;
830 } ;
831
832 return total ;
833} /* ima_write_block */
834
835static sf_count_t
836ima_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
837{ IMA_ADPCM_PRIVATE *pima ;
838 int writecount, count ;
839 sf_count_t total = 0 ;
840
841 if (! psf->codec_data)
842 return 0 ;
843 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
844
845 while (len)
846 { writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
847
848 count = ima_write_block (psf, pima, ptr, writecount) ;
849
850 total += count ;
851 len -= count ;
852 if (count != writecount)
853 break ;
854 } ;
855
856 return total ;
857} /* ima_write_s */
858
859static sf_count_t
860ima_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
861{ IMA_ADPCM_PRIVATE *pima ;
862 BUF_UNION ubuf ;
863 short *sptr ;
864 int k, bufferlen, writecount, count ;
865 sf_count_t total = 0 ;
866
867 if (! psf->codec_data)
868 return 0 ;
869 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
870
871 sptr = ubuf.sbuf ;
872 bufferlen = ARRAY_LEN (ubuf.sbuf)((int) (sizeof (ubuf.sbuf) / sizeof ((ubuf.sbuf) [0]))) ;
873 while (len > 0)
874 { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
875 for (k = 0 ; k < writecount ; k++)
876 sptr [k] = ptr [total + k] >> 16 ;
877 count = ima_write_block (psf, pima, sptr, writecount) ;
878 total += count ;
879 len -= writecount ;
880 if (count != writecount)
881 break ;
882 } ;
883
884 return total ;
885} /* ima_write_i */
886
887static sf_count_t
888ima_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
889{ IMA_ADPCM_PRIVATE *pima ;
890 BUF_UNION ubuf ;
891 short *sptr ;
892 int k, bufferlen, writecount, count ;
893 sf_count_t total = 0 ;
894 float normfact ;
895
896 if (! psf->codec_data)
897 return 0 ;
898 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
899
900 normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
901
902 sptr = ubuf.sbuf ;
903 bufferlen = ARRAY_LEN (ubuf.sbuf)((int) (sizeof (ubuf.sbuf) / sizeof ((ubuf.sbuf) [0]))) ;
904 while (len > 0)
905 { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
906 for (k = 0 ; k < writecount ; k++)
907 sptr [k] = lrintf (normfact * ptr [total + k]) ;
908 count = ima_write_block (psf, pima, sptr, writecount) ;
909 total += count ;
910 len -= writecount ;
911 if (count != writecount)
912 break ;
913 } ;
914
915 return total ;
916} /* ima_write_f */
917
918static sf_count_t
919ima_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
920{ IMA_ADPCM_PRIVATE *pima ;
921 BUF_UNION ubuf ;
922 short *sptr ;
923 int k, bufferlen, writecount, count ;
924 sf_count_t total = 0 ;
925 double normfact ;
926
927 if (! psf->codec_data)
928 return 0 ;
929 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
930
931 normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
932
933 sptr = ubuf.sbuf ;
934 bufferlen = ARRAY_LEN (ubuf.sbuf)((int) (sizeof (ubuf.sbuf) / sizeof ((ubuf.sbuf) [0]))) ;
935 while (len > 0)
936 { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
937 for (k = 0 ; k < writecount ; k++)
938 sptr [k] = lrint (normfact * ptr [total + k]) ;
939 count = ima_write_block (psf, pima, sptr, writecount) ;
940 total += count ;
941 len -= writecount ;
942 if (count != writecount)
943 break ;
944 } ;
945
946 return total ;
947} /* ima_write_d */
948