summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik de Castro Lopo <erikd@mega-nerd.com>2015-02-11 17:21:40 +1100
committerErik de Castro Lopo <erikd@mega-nerd.com>2015-02-10 12:01:51 +1100
commita20f6963506fb2c1e71c7799fe21dec0d35d6712 (patch)
treef7c2ec4e7a11693c74150333dbb8a7ea6a0dfdd8
parentb562efc87e6292fc591b7a3a4187969d5001c157 (diff)
src/ms_adpcm.c : Validate block predictor.
-rw-r--r--src/ms_adpcm.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/src/ms_adpcm.c b/src/ms_adpcm.c
index 09307f7..39f40cf 100644
--- a/src/ms_adpcm.c
+++ b/src/ms_adpcm.c
@@ -1,5 +1,5 @@
/*
-** Copyright (C) 1999-2014 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2015 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -41,6 +41,7 @@
typedef struct
{ int channels, blocksize, samplesperblock, blocks, dataremaining ;
int blockcount ;
+ int sync_error ;
sf_count_t samplecount ;
short *samples ;
unsigned char *block ;
@@ -142,6 +143,7 @@ wav_w64_msadpcm_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
return SFE_MALLOC_FAILED ;
pms = (MSADPCM_PRIVATE*) psf->codec_data ;
+ pms->sync_error = 0 ;
pms->samples = pms->dummydata ;
pms->block = (unsigned char*) (pms->dummydata + psf->sf.channels * samplesperblock) ;
@@ -197,6 +199,20 @@ wav_w64_msadpcm_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
return 0 ;
} /* wav_w64_msadpcm_init */
+
+static inline short
+msadpcm_get_bpred (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms, unsigned char value)
+{ if (value >= MSADPCM_ADAPT_COEFF_COUNT)
+ { if (pms->sync_error == 0)
+ { pms->sync_error = 1 ;
+ psf_log_printf (psf, "MS ADPCM synchronisation error (%u should be < %u).\n", value, MSADPCM_ADAPT_COEFF_COUNT) ;
+ } ;
+ return 0 ;
+ } ;
+ return value ;
+} /* msadpcm_get_bpred */
+
+
static int
msadpcm_decode_block (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms)
{ int chan, k, blockindx, sampleindx ;
@@ -220,10 +236,7 @@ msadpcm_decode_block (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms)
/* Read and check the block header. */
if (pms->channels == 1)
- { bpred [0] = pms->block [0] ;
-
- if (bpred [0] >= 7)
- psf_log_printf (psf, "MS ADPCM synchronisation error (%d).\n", bpred [0]) ;
+ { bpred [0] = msadpcm_get_bpred (psf, pms, pms->block [0]) ;
chan_idelta [0] = pms->block [1] | (pms->block [2] << 8) ;
chan_idelta [1] = 0 ;
@@ -235,11 +248,8 @@ msadpcm_decode_block (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms)
blockindx = 7 ;
}
else
- { bpred [0] = pms->block [0] ;
- bpred [1] = pms->block [1] ;
-
- if (bpred [0] >= 7 || bpred [1] >= 7)
- psf_log_printf (psf, "MS ADPCM synchronisation error (%d %d).\n", bpred [0], bpred [1]) ;
+ { bpred [0] = msadpcm_get_bpred (psf, pms, pms->block [0]) ;
+ bpred [1] = msadpcm_get_bpred (psf, pms, pms->block [1]) ;
chan_idelta [0] = pms->block [2] | (pms->block [3] << 8) ;
chan_idelta [1] = pms->block [4] | (pms->block [5] << 8) ;