Fix ADPCM GetLength() crash.

This commit is contained in:
Glenn Maynard
2003-09-17 01:42:42 +00:00
parent 585b322a96
commit 477402a78c
2 changed files with 48 additions and 16 deletions
+35 -15
View File
@@ -51,13 +51,6 @@ struct ADPCMCOEFSET
Sint16 iCoef1, iCoef2; Sint16 iCoef1, iCoef2;
}; };
struct ADPCMBLOCKHEADER
{
Uint8 bPredictor;
Uint16 iDelta;
Sint16 iSamp[2];
};
/* Call this to convert milliseconds to an actual byte position, based on audio data characteristics. */ /* Call this to convert milliseconds to an actual byte position, based on audio data characteristics. */
Uint32 RageSoundReader_WAV::ConvertMsToBytePos(int BytesPerSample, int channels, Uint32 ms) const Uint32 RageSoundReader_WAV::ConvertMsToBytePos(int BytesPerSample, int channels, Uint32 ms) const
{ {
@@ -137,6 +130,39 @@ bool RageSoundReader_WAV::read_uint8(FILE *rw, Uint8 *ui8) const
return true; return true;
} }
RageSoundReader_WAV::adpcm_t::adpcm_t()
{
memset( this, 0, sizeof(this) );
}
RageSoundReader_WAV::adpcm_t::adpcm_t( const adpcm_t &cpy )
{
memset( this, 0, sizeof(this) );
this->cbSize = cpy.cbSize;
memcpy( this->blockheaders, cpy.blockheaders, sizeof(this->blockheaders) );
this->wSamplesPerBlock = cpy.wSamplesPerBlock;
this->wNumCoef = cpy.wNumCoef;
this->samples_left_in_block = cpy.samples_left_in_block;
this->nibble_state = cpy.nibble_state;
this->nibble = cpy.nibble;
Alloc();
}
void RageSoundReader_WAV::adpcm_t::Alloc()
{
Dealloc();
ASSERT( wNumCoef != 0 );
aCoef = new ADPCMCOEFSET[wNumCoef];
}
void RageSoundReader_WAV::adpcm_t::Dealloc()
{
delete [] aCoef;
aCoef = NULL;
}
bool RageSoundReader_WAV::read_fmt_chunk() bool RageSoundReader_WAV::read_fmt_chunk()
{ {
@@ -155,15 +181,13 @@ bool RageSoundReader_WAV::read_fmt_chunk()
RETURN_IF_MACRO(!read_le16(rw, &adpcm.wSamplesPerBlock), false); RETURN_IF_MACRO(!read_le16(rw, &adpcm.wSamplesPerBlock), false);
RETURN_IF_MACRO(!read_le16(rw, &adpcm.wNumCoef), false); RETURN_IF_MACRO(!read_le16(rw, &adpcm.wNumCoef), false);
adpcm.aCoef = new ADPCMCOEFSET[adpcm.wNumCoef]; adpcm.Alloc();
for (int i = 0; i < adpcm.wNumCoef; i++) for (int i = 0; i < adpcm.wNumCoef; i++)
{ {
RETURN_IF_MACRO(!read_le16(rw, &adpcm.aCoef[i].iCoef1), false); RETURN_IF_MACRO(!read_le16(rw, &adpcm.aCoef[i].iCoef1), false);
RETURN_IF_MACRO(!read_le16(rw, &adpcm.aCoef[i].iCoef2), false); RETURN_IF_MACRO(!read_le16(rw, &adpcm.aCoef[i].iCoef2), false);
} }
adpcm.blockheaders = new ADPCMBLOCKHEADER[fmt.wChannels];
} }
return true; return true;
@@ -211,7 +235,7 @@ int RageSoundReader_WAV::get_length_fmt_adpcm() const
fseek( this->rw, blockno * fmt.wBlockAlign + fmt.data_starting_offset, SEEK_SET ); fseek( this->rw, blockno * fmt.wBlockAlign + fmt.data_starting_offset, SEEK_SET );
/* Don't mess up this->adpcm; we'll put the cursor back as if nothing happened. */ /* Don't mess up this->adpcm; we'll put the cursor back as if nothing happened. */
struct adpcm_t tmp_adpcm; adpcm_t tmp_adpcm(adpcm);
if ( !read_adpcm_block_headers(tmp_adpcm) ) if ( !read_adpcm_block_headers(tmp_adpcm) )
return 0; return 0;
@@ -537,8 +561,6 @@ void RageSoundReader_WAV::Close()
{ {
delete [] this->adpcm.aCoef; delete [] this->adpcm.aCoef;
this->adpcm.aCoef = NULL; this->adpcm.aCoef = NULL;
delete [] this->adpcm.blockheaders;
this->adpcm.blockheaders = NULL;
if( rw ) if( rw )
fclose( rw ); fclose( rw );
@@ -644,8 +666,6 @@ int RageSoundReader_WAV::GetLength() const
RageSoundReader_WAV::RageSoundReader_WAV() RageSoundReader_WAV::RageSoundReader_WAV()
{ {
this->adpcm.aCoef = NULL;
this->adpcm.blockheaders = NULL;
rw = NULL; rw = NULL;
} }
+13 -1
View File
@@ -22,16 +22,28 @@ class RageSoundReader_WAV: public SoundReader_FileReader
Uint32 data_starting_offset; Uint32 data_starting_offset;
} fmt; } fmt;
struct ADPCMBLOCKHEADER {
Uint8 bPredictor;
Uint16 iDelta;
Sint16 iSamp[2];
};
struct adpcm_t struct adpcm_t
{ {
Uint16 cbSize; Uint16 cbSize;
Uint16 wSamplesPerBlock; Uint16 wSamplesPerBlock;
Uint16 wNumCoef; Uint16 wNumCoef;
ADPCMCOEFSET *aCoef; ADPCMCOEFSET *aCoef;
ADPCMBLOCKHEADER *blockheaders;
ADPCMBLOCKHEADER blockheaders[2]; /* 2 channels */
Uint32 samples_left_in_block; Uint32 samples_left_in_block;
int nibble_state; int nibble_state;
Sint8 nibble; Sint8 nibble;
adpcm_t();
~adpcm_t() { Dealloc(); }
adpcm_t( const adpcm_t &cpy );
void Alloc();
void Dealloc();
}; };
struct adpcm_t adpcm; struct adpcm_t adpcm;
CString filename; CString filename;