move exception-based reading into RageFile; this is for concise, error-checked binary file reading
This commit is contained in:
@@ -434,6 +434,51 @@ int RageFile::Seek( int offset, int whence )
|
|||||||
return Seek( (int) offset );
|
return Seek( (int) offset );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileReading::ReadBytes( RageFile &f, void *buf, int size )
|
||||||
|
{
|
||||||
|
int ret = f.Read( buf, size );
|
||||||
|
if( ret == -1 )
|
||||||
|
throw FatalError( f.GetError() );
|
||||||
|
|
||||||
|
if( ret < size )
|
||||||
|
throw UnexpectedEOF();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t FileReading::read_8( RageFile &f )
|
||||||
|
{
|
||||||
|
uint8_t val;
|
||||||
|
ReadBytes( f, &val, sizeof(uint8_t) );
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t FileReading::read_u16_le( RageFile &f )
|
||||||
|
{
|
||||||
|
uint16_t val;
|
||||||
|
ReadBytes( f, &val, sizeof(uint16_t) );
|
||||||
|
return Swap16LE( val );
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t FileReading::read_16_le( RageFile &f )
|
||||||
|
{
|
||||||
|
int16_t val;
|
||||||
|
ReadBytes( f, &val, sizeof(int16_t) );
|
||||||
|
return Swap16LE( val );
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FileReading::read_u32_le( RageFile &f )
|
||||||
|
{
|
||||||
|
uint32_t val;
|
||||||
|
ReadBytes( f, &val, sizeof(uint32_t) );
|
||||||
|
return Swap32LE( val );
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t FileReading::read_32_le( RageFile &f )
|
||||||
|
{
|
||||||
|
int32_t val;
|
||||||
|
ReadBytes( f, &val, sizeof(int32_t) );
|
||||||
|
return Swap32LE( val );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2004 Glenn Maynard, Chris Danford, Steve Checkoway
|
* Copyright (c) 2003-2004 Glenn Maynard, Chris Danford, Steve Checkoway
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
|||||||
@@ -91,4 +91,18 @@ private:
|
|||||||
int m_BufAvail;
|
int m_BufAvail;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* 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 );
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "RageUtil.h"
|
#include "RageUtil.h"
|
||||||
#include "RageLog.h"
|
#include "RageLog.h"
|
||||||
#include "RageSurface.h"
|
#include "RageSurface.h"
|
||||||
|
using namespace FileReading;
|
||||||
|
|
||||||
/* Tested with http://entropymine.com/jason/bmpsuite/. */
|
/* Tested with http://entropymine.com/jason/bmpsuite/. */
|
||||||
|
|
||||||
@@ -16,40 +17,6 @@ enum
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct NotBMP: public RageException { NotBMP(): RageException("not a BMP") { } };
|
struct NotBMP: public RageException { NotBMP(): RageException("not a BMP") { } };
|
||||||
struct FatalError: public RageException { FatalError(const CString &str): RageException(str) { } };
|
|
||||||
struct UnexpectedEOF: public RageException { UnexpectedEOF(): RageException("Unexpected EOF") { } };
|
|
||||||
|
|
||||||
|
|
||||||
static void ReadBytes( RageFile &f, void *buf, int size )
|
|
||||||
{
|
|
||||||
int ret = f.Read( buf, size );
|
|
||||||
if( ret == -1 )
|
|
||||||
throw FatalError( f.GetError() );
|
|
||||||
|
|
||||||
if( ret < size )
|
|
||||||
throw UnexpectedEOF();
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t read_8( RageFile &f )
|
|
||||||
{
|
|
||||||
uint8_t val;
|
|
||||||
ReadBytes( f, &val, sizeof(uint8_t) );
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint16_t read_le16( RageFile &f )
|
|
||||||
{
|
|
||||||
uint16_t val;
|
|
||||||
ReadBytes( f, &val, sizeof(uint16_t) );
|
|
||||||
return Swap16LE( val );
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t read_le32( RageFile &f )
|
|
||||||
{
|
|
||||||
uint32_t val;
|
|
||||||
ReadBytes( f, &val, sizeof(uint32_t) );
|
|
||||||
return Swap32LE( val );
|
|
||||||
}
|
|
||||||
|
|
||||||
static RageSurface *LoadBMP( RageFile &f, RageSurface *&ret )
|
static RageSurface *LoadBMP( RageFile &f, RageSurface *&ret )
|
||||||
{
|
{
|
||||||
@@ -58,32 +25,32 @@ static RageSurface *LoadBMP( RageFile &f, RageSurface *&ret )
|
|||||||
if( magic[0] != 'B' || magic[1] != 'M' )
|
if( magic[0] != 'B' || magic[1] != 'M' )
|
||||||
throw NotBMP();
|
throw NotBMP();
|
||||||
|
|
||||||
read_le32( f ); /* file size */
|
read_u32_le( f ); /* file size */
|
||||||
read_le32( f ); /* unused */
|
read_u32_le( f ); /* unused */
|
||||||
uint32_t iDataOffset = read_le32( f );
|
uint32_t iDataOffset = read_u32_le( f );
|
||||||
uint32_t iHeaderSize = read_le32( f );
|
uint32_t iHeaderSize = read_u32_le( f );
|
||||||
|
|
||||||
uint32_t iWidth, iHeight, iPlanes, iBPP, iCompression = COMP_BI_RGB, iColors = 0;
|
uint32_t iWidth, iHeight, iPlanes, iBPP, iCompression = COMP_BI_RGB, iColors = 0;
|
||||||
if( iHeaderSize == 12 )
|
if( iHeaderSize == 12 )
|
||||||
{
|
{
|
||||||
/* OS/2 format */
|
/* OS/2 format */
|
||||||
iWidth = read_le16( f );
|
iWidth = read_u16_le( f );
|
||||||
iHeight = read_le16( f );
|
iHeight = read_u16_le( f );
|
||||||
iPlanes = read_le16( f );
|
iPlanes = read_u16_le( f );
|
||||||
iBPP = read_le16( f );
|
iBPP = read_u16_le( f );
|
||||||
}
|
}
|
||||||
else if( iHeaderSize == 40 )
|
else if( iHeaderSize == 40 )
|
||||||
{
|
{
|
||||||
iWidth = read_le32( f );
|
iWidth = read_u32_le( f );
|
||||||
iHeight = read_le32( f );
|
iHeight = read_u32_le( f );
|
||||||
iPlanes = read_le16( f );
|
iPlanes = read_u16_le( f );
|
||||||
iBPP = read_le16( f );
|
iBPP = read_u16_le( f );
|
||||||
iCompression = read_le32( f );
|
iCompression = read_u32_le( f );
|
||||||
read_le32( f ); /* bitmap size */
|
read_u32_le( f ); /* bitmap size */
|
||||||
read_le32( f ); /* horiz resolution */
|
read_u32_le( f ); /* horiz resolution */
|
||||||
read_le32( f ); /* vert resolution */
|
read_u32_le( f ); /* vert resolution */
|
||||||
iColors = read_le32( f );
|
iColors = read_u32_le( f );
|
||||||
read_le32( f ); /* "important" colors */
|
read_u32_le( f ); /* "important" colors */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw FatalError( ssprintf( "expected header size of 40, got %u", iHeaderSize ) );
|
throw FatalError( ssprintf( "expected header size of 40, got %u", iHeaderSize ) );
|
||||||
@@ -125,9 +92,9 @@ static RageSurface *LoadBMP( RageFile &f, RageSurface *&ret )
|
|||||||
|
|
||||||
if( iCompression == COMP_BI_BITFIELDS )
|
if( iCompression == COMP_BI_BITFIELDS )
|
||||||
{
|
{
|
||||||
Rmask = read_le32( f );
|
Rmask = read_u32_le( f );
|
||||||
Gmask = read_le32( f );
|
Gmask = read_u32_le( f );
|
||||||
Bmask = read_le32( f );
|
Bmask = read_u32_le( f );
|
||||||
}
|
}
|
||||||
|
|
||||||
RageSurface *img = CreateSurface( iWidth, iHeight, iBPP, Rmask, Gmask, Bmask, Amask );
|
RageSurface *img = CreateSurface( iWidth, iHeight, iBPP, Rmask, Gmask, Bmask, Amask );
|
||||||
@@ -224,9 +191,6 @@ RageSurfaceUtils::OpenResult RageSurface_Load_BMP( const CString &sPath, RageSur
|
|||||||
} catch( const FatalError &err ) {
|
} catch( const FatalError &err ) {
|
||||||
error = err.what();
|
error = err.what();
|
||||||
return RageSurfaceUtils::OPEN_FATAL_ERROR;
|
return RageSurfaceUtils::OPEN_FATAL_ERROR;
|
||||||
} catch( const UnexpectedEOF & ) {
|
|
||||||
error = "unexpected end of file";
|
|
||||||
return RageSurfaceUtils::OPEN_FATAL_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return RageSurfaceUtils::OPEN_OK;
|
return RageSurfaceUtils::OPEN_OK;
|
||||||
|
|||||||
Reference in New Issue
Block a user