From b6eba6ac8d4a9061f5d9de7181c779c12920cefd Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Tue, 30 Nov 2004 08:12:08 +0000 Subject: [PATCH] start eliminating exception use; gcc apparently bloats exceptions to a degree that makes them not worth it --- stepmania/src/RageFile.cpp | 57 +++++--- stepmania/src/RageFile.h | 17 ++- stepmania/src/RageSoundReader_WAV.cpp | 178 +++++++++++++++---------- stepmania/src/RageSoundReader_WAV.h | 1 - stepmania/src/RageSurface_Load_BMP.cpp | 125 +++++++++-------- 5 files changed, 220 insertions(+), 158 deletions(-) diff --git a/stepmania/src/RageFile.cpp b/stepmania/src/RageFile.cpp index af19772d14..84c08afa6d 100644 --- a/stepmania/src/RageFile.cpp +++ b/stepmania/src/RageFile.cpp @@ -436,49 +436,66 @@ int RageFile::Seek( int offset, int whence ) return Seek( (int) offset ); } -void FileReading::ReadBytes( RageFile &f, void *buf, int size ) +void FileReading::ReadBytes( RageFile &f, void *buf, int size, CString &sError ) { + if( sError.size() != 0 ) + return; + int ret = f.Read( buf, size ); if( ret == -1 ) - throw FatalError( f.GetError() ); - - if( ret < size ) - throw UnexpectedEOF(); + sError = f.GetError(); + else if( ret < size ) + sError = "Unexpected end of file"; } -uint8_t FileReading::read_8( RageFile &f ) +uint8_t FileReading::read_8( RageFile &f, CString &sError ) { uint8_t val; - ReadBytes( f, &val, sizeof(uint8_t) ); - return val; + ReadBytes( f, &val, sizeof(uint8_t), sError ); + if( sError.size() == 0 ) + return val; + else + return 0; } -uint16_t FileReading::read_u16_le( RageFile &f ) +uint16_t FileReading::read_u16_le( RageFile &f, CString &sError ) { uint16_t val; - ReadBytes( f, &val, sizeof(uint16_t) ); - return Swap16LE( val ); + ReadBytes( f, &val, sizeof(uint16_t), sError ); + if( sError.size() == 0 ) + return Swap16LE( val ); + else + return 0; } -int16_t FileReading::read_16_le( RageFile &f ) +int16_t FileReading::read_16_le( RageFile &f, CString &sError ) { int16_t val; - ReadBytes( f, &val, sizeof(int16_t) ); - return Swap16LE( val ); + ReadBytes( f, &val, sizeof(int16_t), sError ); + if( sError.size() == 0 ) + return Swap16LE( val ); + else + return 0; } -uint32_t FileReading::read_u32_le( RageFile &f ) +uint32_t FileReading::read_u32_le( RageFile &f, CString &sError ) { uint32_t val; - ReadBytes( f, &val, sizeof(uint32_t) ); - return Swap32LE( val ); + ReadBytes( f, &val, sizeof(uint32_t), sError ); + if( sError.size() == 0 ) + return Swap32LE( val ); + else + return 0; } -int32_t FileReading::read_32_le( RageFile &f ) +int32_t FileReading::read_32_le( RageFile &f, CString &sError ) { int32_t val; - ReadBytes( f, &val, sizeof(int32_t) ); - return Swap32LE( val ); + ReadBytes( f, &val, sizeof(int32_t), sError ); + if( sError.size() == 0 ) + return Swap32LE( val ); + else + return 0; } /* diff --git a/stepmania/src/RageFile.h b/stepmania/src/RageFile.h index 45c737c37a..afcc2afed6 100644 --- a/stepmania/src/RageFile.h +++ b/stepmania/src/RageFile.h @@ -94,15 +94,14 @@ private: /* Convenience wrappers for reading binary files. */ namespace FileReading { - struct FatalError: public RageException { FatalError(const CString &str): RageException(str) { } }; - struct UnexpectedEOF: public FatalError { UnexpectedEOF(): FatalError("Unexpected end of file") { } }; - - void ReadBytes( RageFile &f, void *buf, int size ); - uint8_t read_8( RageFile &f ); - int16_t read_16_le( RageFile &f ); - uint16_t read_u16_le( RageFile &f ); - int32_t read_32_le( RageFile &f ); - uint32_t read_u32_le( RageFile &f ); + /* On error, these set sError to the error message. If sError is already + * non-empty, nothing happens. */ + void ReadBytes( RageFile &f, void *buf, int size, CString &sError ); + uint8_t read_8( RageFile &f, CString &sError ); + int16_t read_16_le( RageFile &f, CString &sError ); + uint16_t read_u16_le( RageFile &f, CString &sError ); + int32_t read_32_le( RageFile &f, CString &sError ); + uint32_t read_u32_le( RageFile &f, CString &sError ); }; #endif diff --git a/stepmania/src/RageSoundReader_WAV.cpp b/stepmania/src/RageSoundReader_WAV.cpp index 06d6a96986..8fc333de4f 100644 --- a/stepmania/src/RageSoundReader_WAV.cpp +++ b/stepmania/src/RageSoundReader_WAV.cpp @@ -44,7 +44,7 @@ struct WavReader virtual ~WavReader() { } virtual int Read( char *buf, unsigned len ) = 0; virtual int GetLength() const = 0; - virtual void Init() = 0; + virtual bool Init() = 0; virtual int SetPosition( int iMS ) = 0; CString GetError() const { return m_sError; } @@ -59,12 +59,16 @@ struct WavReaderPCM: public WavReader WavReaderPCM( RageFile &f, const RageSoundReader_WAV::WavData &data ): WavReader(f, data) { } - void Init() + bool Init() { if( m_WavData.m_iBitsPerSample != 8 && m_WavData.m_iBitsPerSample != 16 ) - throw FileReading::FatalError( ssprintf("Unsupported sample size %i", m_WavData.m_iBitsPerSample) ); + { + m_sError = ssprintf("Unsupported sample size %i", m_WavData.m_iBitsPerSample); + return false; + } m_File.Seek( m_WavData.m_iDataChunkPos ); + return true; } int Read( char *buf, unsigned len ) @@ -132,27 +136,34 @@ public: delete[] m_pBuffer; } - void Init() + bool Init() { if( m_WavData.m_iBitsPerSample != 4 ) - throw FileReading::FatalError( ssprintf( "Unsupported ADPCM sample size %i", m_WavData.m_iBitsPerSample ) ); + { + m_sError = ssprintf( "Unsupported ADPCM sample size %i", m_WavData.m_iBitsPerSample ); + return false; + } m_File.Seek( m_WavData.m_iExtraFmtPos ); - m_iFramesPerBlock = FileReading::read_16_le( m_File ); - int16_t iNumCoef = FileReading::read_16_le( m_File ); + m_iFramesPerBlock = FileReading::read_16_le( m_File, m_sError ); + int16_t iNumCoef = FileReading::read_16_le( m_File, m_sError ); m_iaCoef1.resize( iNumCoef ); m_iaCoef2.resize( iNumCoef ); for( int i = 0; i < iNumCoef; ++i ) { - m_iaCoef1[i] = FileReading::read_16_le( m_File ); - m_iaCoef2[i] = FileReading::read_16_le( m_File ); + m_iaCoef1[i] = FileReading::read_16_le( m_File, m_sError ); + m_iaCoef2[i] = FileReading::read_16_le( m_File, m_sError ); } + if( m_sError.size() != 0 ) + return false; + m_pBuffer = new int8_t[m_iFramesPerBlock*m_WavData.m_iChannels*sizeof(int16_t)]; m_iBufferAvail = m_iBufferUsed = 0; m_File.Seek( m_WavData.m_iDataChunkPos ); + return true; } void SetEOF() @@ -162,7 +173,7 @@ public: } /* Return false on error, true on success (even if we hit EOF). */ - void DecodeADPCMBlock() + bool DecodeADPCMBlock() { ASSERT_M( m_iBufferUsed == m_iBufferAvail, ssprintf("%i", m_iBufferUsed) ); @@ -171,25 +182,31 @@ public: int8_t iPredictor[2]; int16_t iDelta[2], iSamp1[2], iSamp2[2]; for( int i = 0; i < m_WavData.m_iChannels; ++i ) - iPredictor[i] = FileReading::read_8( m_File ); + iPredictor[i] = FileReading::read_8( m_File, m_sError ); for( int i = 0; i < m_WavData.m_iChannels; ++i ) - iDelta[i] = FileReading::read_16_le( m_File ); + iDelta[i] = FileReading::read_16_le( m_File, m_sError ); for( int i = 0; i < m_WavData.m_iChannels; ++i ) - iSamp1[i] = FileReading::read_16_le( m_File ); + iSamp1[i] = FileReading::read_16_le( m_File, m_sError ); for( int i = 0; i < m_WavData.m_iChannels; ++i ) - iSamp2[i] = FileReading::read_16_le( m_File ); + iSamp2[i] = FileReading::read_16_le( m_File, m_sError ); + + if( m_sError.size() != 0 ) + return false; if( m_File.Tell() >= m_WavData.m_iDataChunkSize+m_WavData.m_iDataChunkPos || m_File.AtEOF() ) - return; /* past the data chunk */ - - CString sError; + return true; /* past the data chunk */ int16_t *pBuffer = (int16_t *) m_pBuffer; int iCoef1[2], iCoef2[2]; for( int i = 0; i < m_WavData.m_iChannels; ++i ) { if( iPredictor[i] >= (int) m_iaCoef1.size() ) - throw FileReading::FatalError( "Predictor out of range" ); + { + LOG->Trace( "%s: predictor out of range", m_File.GetPath().c_str() ); + + /* XXX: silence this block? */ + iPredictor[i] = 0; + } iCoef1[i] = m_iaCoef1[iPredictor[i]]; iCoef2[i] = m_iaCoef2[iPredictor[i]]; @@ -203,7 +220,12 @@ public: int iBlockSize = m_File.Read( pBuf, iMaxSize ); if( iBlockSize == 0 ) - return; + return true; + if( iBlockSize == -1 ) + { + m_sError = m_File.GetError(); + return false; + } for( int i = 0; i < m_WavData.m_iChannels; ++i ) pBuffer[m_iBufferAvail++] = iSamp2[i]; @@ -254,6 +276,7 @@ public: } m_iBufferAvail *= sizeof(int16_t); + return true; } int Read( char *buf, unsigned len ) @@ -263,12 +286,8 @@ public: { if( m_iBufferUsed == m_iBufferAvail ) { - try { - DecodeADPCMBlock(); - } catch( const FileReading::FatalError &err ) { - m_sError = err.what(); + if( !DecodeADPCMBlock() ) return -1; - } } if( m_iBufferAvail == 0 ) break; /* EOF */ @@ -320,12 +339,8 @@ public: m_File.Seek( iByte+m_WavData.m_iDataChunkPos ); } - try { - DecodeADPCMBlock(); - } catch( const FileReading::FatalError &err ) { - m_sError = err.what(); + if( !DecodeADPCMBlock() ) return -1; - } const int iRemainingFrames = iFrame - iBlock*m_iFramesPerBlock; m_iBufferUsed = iRemainingFrames * m_WavData.m_iChannels * sizeof(int16_t); @@ -338,34 +353,62 @@ public: return iMS; } }; -struct NotWAV: public RageException { NotWAV(): RageException("not a WAV") { } }; -CString ReadString( RageFile &f, int iSize ) +CString ReadString( RageFile &f, int iSize, CString &sError ) { + if( sError.size() != 0 ) + return ""; + CString sBuf; char *pBuf = sBuf.GetBuffer( iSize ); - FileReading::ReadBytes( f, pBuf, iSize ); + FileReading::ReadBytes( f, pBuf, iSize, sError ); sBuf.ReleaseBuffer( iSize ); return sBuf; } -void RageSoundReader_WAV::OpenInternal() +#define FATAL_ERROR(s) \ +{ \ + if( sError.size() == 0 ) sError = (s); \ + SetError( sError ); \ + return OPEN_FATAL_ERROR; \ +} + +SoundReader_FileReader::OpenResult RageSoundReader_WAV::Open( CString filename_ ) { + m_sFilename = filename_; + + CString sError; + + if( !m_File.Open( m_sFilename ) ) + FATAL_ERROR( ssprintf("wav: opening \"%s\" failed: %s", m_sFilename.c_str(), m_File.GetError().c_str()) ); + /* RIFF header: */ - if( ReadString( m_File, 4 ) != "RIFF" ) - throw NotWAV(); - FileReading::read_32_le( m_File ); /* file size */ - if( ReadString( m_File, 4 ) != "WAVE" ) - throw NotWAV(); + if( ReadString( m_File, 4, sError ) != "RIFF" ) + { + SetError( "Not a WAV file" ); + return OPEN_UNKNOWN_FILE_FORMAT; + } + + FileReading::read_32_le( m_File, sError ); /* file size */ + if( ReadString( m_File, 4, sError ) != "WAVE" ) + { + SetError( "Not a WAV file" ); + return OPEN_UNKNOWN_FILE_FORMAT; + } int16_t iFormatTag = 0; bool bGotFormatChunk = false, bGotDataChunk = false; while( !bGotFormatChunk || !bGotDataChunk ) { - CString ChunkID = ReadString( m_File, 4 ); + CString ChunkID = ReadString( m_File, 4, sError ); + int32_t iChunkSize = FileReading::read_32_le( m_File, sError ); - int32_t iChunkSize = FileReading::read_32_le( m_File ); + if( sError.size() != 0 ) + { + SetError( sError ); + return OPEN_FATAL_ERROR; + } int iNextChunk = m_File.Tell() + iChunkSize; /* Chunks are always word-aligned: */ @@ -376,19 +419,19 @@ void RageSoundReader_WAV::OpenInternal() if( bGotFormatChunk ) LOG->Warn( "File %s has more than one fmt chunk", m_File.GetPath().c_str() ); - iFormatTag = FileReading::read_16_le( m_File ); - m_WavData.m_iChannels = FileReading::read_16_le( m_File ); - m_WavData.m_iSampleRate = FileReading::read_32_le( m_File ); - FileReading::read_32_le( m_File ); /* BytesPerSec */ - m_WavData.m_iBlockAlign = FileReading::read_16_le( m_File ); - m_WavData.m_iBitsPerSample = FileReading::read_16_le( m_File ); - m_WavData.m_iExtraFmtBytes = FileReading::read_16_le( m_File ); + iFormatTag = FileReading::read_16_le( m_File, sError ); + m_WavData.m_iChannels = FileReading::read_16_le( m_File, sError ); + m_WavData.m_iSampleRate = FileReading::read_32_le( m_File, sError ); + FileReading::read_32_le( m_File, sError ); /* BytesPerSec */ + m_WavData.m_iBlockAlign = FileReading::read_16_le( m_File, sError ); + m_WavData.m_iBitsPerSample = FileReading::read_16_le( m_File, sError ); + m_WavData.m_iExtraFmtBytes = FileReading::read_16_le( m_File, sError ); if( m_WavData.m_iChannels < 1 || m_WavData.m_iChannels > 2 ) - throw FileReading::FatalError( ssprintf( "Unsupported channel count: %i", m_WavData.m_iChannels) ); + FATAL_ERROR( ssprintf( "Unsupported channel count: %i", m_WavData.m_iChannels) ); if( m_WavData.m_iSampleRate < 4000 || m_WavData.m_iSampleRate > 100000 ) /* unlikely */ - throw FileReading::FatalError( ssprintf( "Invalid sample rate: %i", m_WavData.m_iSampleRate) ); + FATAL_ERROR( ssprintf( "Invalid sample rate: %i", m_WavData.m_iSampleRate) ); m_WavData.m_iExtraFmtPos = m_File.Tell(); @@ -415,6 +458,12 @@ void RageSoundReader_WAV::OpenInternal() m_File.Seek( iNextChunk ); } + if( sError.size() != 0 ) + { + SetError( sError ); + return OPEN_FATAL_ERROR; + } + switch( iFormatTag ) { case 1: // PCM @@ -425,31 +474,14 @@ void RageSoundReader_WAV::OpenInternal() break; case 85: // MP3 /* Return unknown, so other decoders will be tried. MAD can read MP3s embedded in WAVs. */ - throw NotWAV(); - default: - throw FileReading::FatalError( ssprintf( "Unsupported data format %i", iFormatTag) ); - } - - m_pImpl->Init(); -} - -SoundReader_FileReader::OpenResult RageSoundReader_WAV::Open( CString filename_ ) -{ - m_sFilename = filename_; - - if( !m_File.Open( m_sFilename ) ) - { - SetError( ssprintf("wav: opening \"%s\" failed: %s", m_sFilename.c_str(), m_File.GetError().c_str()) ); - return OPEN_FATAL_ERROR; - } - - try { - OpenInternal(); - } catch( const NotWAV &err ) { - SetError( err.what() ); return OPEN_UNKNOWN_FILE_FORMAT; - } catch( const FileReading::FatalError &err ) { - SetError( err.what() ); + default: + FATAL_ERROR( ssprintf( "Unsupported data format %i", iFormatTag) ); + } + + if( !m_pImpl->Init() ) + { + SetError( m_pImpl->GetError() ); return OPEN_FATAL_ERROR; } diff --git a/stepmania/src/RageSoundReader_WAV.h b/stepmania/src/RageSoundReader_WAV.h index 3ff950efbe..fb8a318520 100644 --- a/stepmania/src/RageSoundReader_WAV.h +++ b/stepmania/src/RageSoundReader_WAV.h @@ -37,7 +37,6 @@ private: WavReader *m_pImpl; - void OpenInternal(); int SetPosition( int ms ); }; diff --git a/stepmania/src/RageSurface_Load_BMP.cpp b/stepmania/src/RageSurface_Load_BMP.cpp index 372614b7cf..a743ec4d1c 100644 --- a/stepmania/src/RageSurface_Load_BMP.cpp +++ b/stepmania/src/RageSurface_Load_BMP.cpp @@ -16,56 +16,68 @@ enum COMP_BI_BITFIELDS }; -struct NotBMP: public RageException { NotBMP(): RageException("not a BMP") { } }; -static RageSurface *LoadBMP( RageFile &f, RageSurface *&ret ) +/* When returning error, the first error encountered takes priority. */ +#define FATAL_ERROR(s) \ +{ \ + if( sError.size() == 0 ) sError = (s); \ + return RageSurfaceUtils::OPEN_FATAL_ERROR; \ +} + +static RageSurfaceUtils::OpenResult LoadBMP( RageFile &f, RageSurface *&img, CString &sError ) { char magic[2]; - ReadBytes( f, magic, 2 ); + ReadBytes( f, magic, 2, sError ); if( magic[0] != 'B' || magic[1] != 'M' ) - throw NotBMP(); + { + sError = "not a BMP"; + return RageSurfaceUtils::OPEN_UNKNOWN_FILE_FORMAT; + } + + img = NULL; + + read_u32_le( f, sError ); /* file size */ + read_u32_le( f, sError ); /* unused */ + uint32_t iDataOffset = read_u32_le( f, sError ); + uint32_t iHeaderSize = read_u32_le( f, sError ); - read_u32_le( f ); /* file size */ - read_u32_le( f ); /* unused */ - uint32_t iDataOffset = read_u32_le( f ); - uint32_t iHeaderSize = read_u32_le( f ); uint32_t iWidth, iHeight, iPlanes, iBPP, iCompression = COMP_BI_RGB, iColors = 0; if( iHeaderSize == 12 ) { /* OS/2 format */ - iWidth = read_u16_le( f ); - iHeight = read_u16_le( f ); - iPlanes = read_u16_le( f ); - iBPP = read_u16_le( f ); + iWidth = read_u16_le( f, sError ); + iHeight = read_u16_le( f, sError ); + iPlanes = read_u16_le( f, sError ); + iBPP = read_u16_le( f, sError ); } else if( iHeaderSize == 40 ) { - iWidth = read_u32_le( f ); - iHeight = read_u32_le( f ); - iPlanes = read_u16_le( f ); - iBPP = read_u16_le( f ); - iCompression = read_u32_le( f ); - read_u32_le( f ); /* bitmap size */ - read_u32_le( f ); /* horiz resolution */ - read_u32_le( f ); /* vert resolution */ - iColors = read_u32_le( f ); - read_u32_le( f ); /* "important" colors */ + iWidth = read_u32_le( f, sError ); + iHeight = read_u32_le( f, sError ); + iPlanes = read_u16_le( f, sError ); + iBPP = read_u16_le( f, sError ); + iCompression = read_u32_le( f, sError ); + read_u32_le( f, sError ); /* bitmap size */ + read_u32_le( f, sError ); /* horiz resolution */ + read_u32_le( f, sError ); /* vert resolution */ + iColors = read_u32_le( f, sError ); + read_u32_le( f, sError ); /* "important" colors */ } else - throw FatalError( ssprintf( "expected header size of 40, got %u", iHeaderSize ) ); + FATAL_ERROR( ssprintf( "expected header size of 40, got %u", iHeaderSize ) ); if( iBPP <= 8 && iColors == 0 ) iColors = 1 << iBPP; if( iPlanes != 1 ) - throw FatalError( ssprintf( "expected one plane, got %u", iPlanes ) ); + FATAL_ERROR( ssprintf( "expected one plane, got %u", iPlanes ) ); if( iBPP != 1 && iBPP != 4 && iBPP != 8 && iBPP != 16 && iBPP != 24 && iBPP != 32 ) - throw FatalError( ssprintf( "unsupported bpp %u", iBPP ) ); + FATAL_ERROR( ssprintf( "unsupported bpp %u", iBPP ) ); if( iCompression != COMP_BI_RGB && iCompression != COMP_BI_BITFIELDS ) - throw FatalError( ssprintf( "unsupported compression %u", iCompression ) ); + FATAL_ERROR( ssprintf( "unsupported compression %u", iCompression ) ); if( iCompression == COMP_BI_BITFIELDS && iBPP <= 8 ) - throw FatalError( ssprintf( "BI_BITFIELDS unexpected with bpp %u", iBPP ) ); + FATAL_ERROR( ssprintf( "BI_BITFIELDS unexpected with bpp %u", iBPP ) ); int iFileBPP = iBPP; iBPP = max( iBPP, 8u ); @@ -92,36 +104,43 @@ static RageSurface *LoadBMP( RageFile &f, RageSurface *&ret ) if( iCompression == COMP_BI_BITFIELDS ) { - Rmask = read_u32_le( f ); - Gmask = read_u32_le( f ); - Bmask = read_u32_le( f ); + Rmask = read_u32_le( f, sError ); + Gmask = read_u32_le( f, sError ); + Bmask = read_u32_le( f, sError ); } - RageSurface *img = CreateSurface( iWidth, iHeight, iBPP, Rmask, Gmask, Bmask, Amask ); + /* Stop on error before we use any of the values we just read. */ + if( sError.size() != 0 ) + return RageSurfaceUtils::OPEN_FATAL_ERROR; + + img = CreateSurface( iWidth, iHeight, iBPP, Rmask, Gmask, Bmask, Amask ); -try { /* file reading may throw */ if( iBPP == 8 ) { RageSurfaceColor Palette[256]; ZERO( Palette ); if( iColors > 256 ) - throw FatalError( ssprintf( "unexpected colors %i", iColors ) ); + FATAL_ERROR( ssprintf( "unexpected colors %i", iColors ) ); for( unsigned i = 0; i < iColors; ++i ) { - Palette[i].b = read_8( f ); - Palette[i].g = read_8( f ); - Palette[i].r = read_8( f ); + Palette[i].b = read_8( f, sError ); + Palette[i].g = read_8( f, sError ); + Palette[i].r = read_8( f, sError ); Palette[i].a = 0xFF; /* Windows BMP palettes are padded to 32bpp. */ if( iHeaderSize == 40 ) - read_8( f ); + read_8( f, sError ); } memcpy( img->fmt.palette->colors, Palette, sizeof(Palette) ); } + /* Stop on error before we seek, so we don't return the wrong error message. */ + if( sError.size() != 0 ) + return RageSurfaceUtils::OPEN_FATAL_ERROR; + int iFilePitch = iFileBPP * iWidth; // in bits iFilePitch = (iFilePitch+7) / 8; // in bytes: round up iFilePitch = (iFilePitch+3) & ~3; // round up a multiple of 4 @@ -129,9 +148,9 @@ try { /* file reading may throw */ { int ret = f.Seek( iDataOffset ); if( ret == -1 ) - throw FatalError( f.GetError() ); + FATAL_ERROR( f.GetError() ); if( ret != (int) iDataOffset ) - throw UnexpectedEOF(); + FATAL_ERROR( "Unexpected end of file" ); } for( int y = (int) iHeight-1; y >= 0; --y ) @@ -165,15 +184,11 @@ try { /* file reading may throw */ else memcpy( pRow, buf.data(), img->pitch ); } -} catch(...) { - delete img; - throw; + + return sError.size() != 0? RageSurfaceUtils::OPEN_FATAL_ERROR: RageSurfaceUtils::OPEN_OK; } - return img; -} - -RageSurfaceUtils::OpenResult RageSurface_Load_BMP( const CString &sPath, RageSurface *&ret, bool bHeaderOnly, CString &error ) +RageSurfaceUtils::OpenResult RageSurface_Load_BMP( const CString &sPath, RageSurface *&img, bool bHeaderOnly, CString &error ) { RageFile f; @@ -183,17 +198,17 @@ RageSurfaceUtils::OpenResult RageSurface_Load_BMP( const CString &sPath, RageSur return RageSurfaceUtils::OPEN_FATAL_ERROR; } - try { - ret = LoadBMP( f, ret ); - } catch( const NotBMP & ) { - error = "not a BMP"; - return RageSurfaceUtils::OPEN_UNKNOWN_FILE_FORMAT; - } catch( const FatalError &err ) { - error = err.what(); - return RageSurfaceUtils::OPEN_FATAL_ERROR; + RageSurfaceUtils::OpenResult ret; + img = NULL; + ret = LoadBMP( f, img, error ); + + if( ret != RageSurfaceUtils::OPEN_OK && img != NULL ) + { + delete img; + img = NULL; } - return RageSurfaceUtils::OPEN_OK; + return ret; } /*