diff options
| -rw-r--r-- | graphics/ilbm.cpp | 227 | ||||
| -rw-r--r-- | graphics/ilbm.h | 127 | 
2 files changed, 273 insertions, 81 deletions
diff --git a/graphics/ilbm.cpp b/graphics/ilbm.cpp index b44d3799b2..e0c53ac0be 100644 --- a/graphics/ilbm.cpp +++ b/graphics/ilbm.cpp @@ -23,75 +23,10 @@  #include "common/endian.h"  #include "common/stream.h"  #include "graphics/surface.h" +#include "graphics/ilbm.h"  namespace Graphics { -typedef uint32 IFF_ID; - -struct Chunk { -	IFF_ID id; -	uint32 size; -	uint32 bytesRead; -	Common::ReadStream *_input; - -	Chunk(Common::ReadStream *input): _input(input) { -		size = bytesRead = 0; -	} - -	void incBytesRead(uint32 inc) { -		bytesRead += inc; -		if (bytesRead > size) { -			error("Chunk overead"); -		} -	} - -	void readHeader() { -		id = _input->readUint32BE(); -		size = _input->readUint32BE(); -		bytesRead = 0; -	} - -	bool eos() { -		return (size - bytesRead) == 0; -	} - -	void feed() { -		if (size % 2) { -			size++; -		} -		while (!_input->eos() && !eos()) { -			readByte(); -		} -	} - -	byte readByte() { -		incBytesRead(1); -		return _input->readByte(); -	} - -	int8 readSByte() { -		incBytesRead(1); -		return _input->readSByte(); -	} - -	uint16 readUint16() { -		incBytesRead(2); -		return _input->readUint16BE(); -	} - -	uint32 readUint32() { -		incBytesRead(4); -		return _input->readUint32BE(); -	} - -	int16 readSint16() { -		return (int16)readUint16(); -	} - -	int32 readSint32() { -		return (int32)readUint32(); -	} -};  static char * ID2string(IFF_ID id) {  	static char str[] = "abcd"; @@ -105,21 +40,6 @@ static char * ID2string(IFF_ID id) {  } -struct BMHD { -	uint16 width, height; -	uint16 x, y; -	byte depth; -	byte masking; -	byte pack; -	byte flags; -	uint16 transparentColor; -	byte xAspect, yAspect; -	uint16 pageWidth, pageHeight; -	BMHD() { -		memset(this, 0, sizeof(*this)); -	} -}; -  #define ID_FORM     MKID_BE('FORM')  /* EA IFF 85 group identifier */  #define ID_CAT      MKID_BE('CAT ') @@ -219,6 +139,151 @@ page 376) */  /* ? */ +void IFFDecoder::readBMHD() { + +	_bitmapHeader.width = _chunk.readUint16(); +	_bitmapHeader.height = _chunk.readUint16(); +	_bitmapHeader.x = _chunk.readUint16(); +	_bitmapHeader.y = _chunk.readUint16(); + +	_bitmapHeader.depth = _chunk.readByte(); +	_bitmapHeader.masking = _chunk.readByte(); +	_bitmapHeader.pack = _chunk.readByte(); +	_bitmapHeader.flags = _chunk.readByte(); +	_bitmapHeader.transparentColor = _chunk.readUint16(); +	_bitmapHeader.xAspect = _chunk.readByte(); +	_bitmapHeader.yAspect = _chunk.readByte(); +	_bitmapHeader.pageWidth = _chunk.readUint16(); +	_bitmapHeader.pageHeight = _chunk.readUint16(); + + +	_colorCount = 1 << _bitmapHeader.depth; +	_colors = (byte*)malloc(sizeof(*_colors) * _colorCount * 3); +	_surface->create(_bitmapHeader.width, _bitmapHeader.height, 1); + +} + +void IFFDecoder::readCMAP() { +	if (_colors == NULL) { +		error("wrong input chunk sequence"); +	} +	for (uint32 i = 0; i < _colorCount; i++) { +		_colors[i * 3 + 0] = _chunk.readByte(); +		_colors[i * 3 + 1] = _chunk.readByte(); +		_colors[i * 3 + 2] = _chunk.readByte(); +	} +} + +IFFDecoder::IFFDecoder(Common::ReadStream &input) : _formChunk(&input), _chunk(&input), _colorCount(0) { +	_formChunk.readHeader(); +	if (_formChunk.id != ID_FORM) { +		error("IFFDecoder input is not a FORM type IFF file"); +	} +} + +IFFDecoder::~IFFDecoder() { +} + +void IFFDecoder::decode(Surface &surface, byte *&colors) { +	_surface = &surface; +	_colors = colors; + +	if (!isTypeSupported(_formChunk.readUint32())) { +		error( "IFFDecoder input is not a valid subtype"); +	} + +	while (!_formChunk.eos()) { +		_formChunk.incBytesRead(8); +		_chunk.readHeader(); + +		switch (_chunk.id) { +		case ID_BMHD: +			readBMHD(); +			break; + +		case ID_CMAP: +			readCMAP(); +			break; + +		case ID_BODY: +			readBODY(); +			break; + +		case ID_CRNG: +//				readCRNG(); +			break; + +		case ID_GRAB: case ID_TINY: case ID_DPPS: +			break; + +		default: +			error("unknown chunk : %s\n", ID2string(_chunk.id)); +		} + +		_chunk.feed(); +		_formChunk.incBytesRead(_chunk.size); + +	} +} + + + +bool PBMDecoder::isTypeSupported(IFF_ID type) { +	return type == ID_PBM; +} + +void PBMDecoder::readBody() { +	byte byteRun; +	byte idx; +	uint32 si = 0, i, j; + +	if (_bitmapHeader.depth > 8) { +		error("PBMDecoder depth > 8"); +	} + +	if ((_bitmapHeader.pack != 0) && (_bitmapHeader.pack != 1)) { +		error("PBMDecoder unsupported pack"); +	} + +	switch (_bitmapHeader.pack) { +	case 0: +		while (!_chunk.eos()) { +			idx = _chunk.readByte(); +			((byte*)_surface->pixels)[si++] = idx; +		} +		break; +	case 1: +		while (!_chunk.eos()) { +			byteRun = _chunk.readByte(); +			if (byteRun <= 127) { +				i = byteRun + 1; +				for (j = 0; j < i; j++){ +					idx = _chunk.readByte(); +					((byte*)_surface->pixels)[si++] = idx; +				} +			} else if (byteRun != 128) { +				i = (256 - byteRun) + 1; +				idx = _chunk.readByte(); +				for (j = 0; j < i; j++) { +					((byte*)_surface->pixels)[si++] = idx; +				} +			} +		} +		break; +	} + +} + +PBMDecoder::PBMDecoder(Common::ReadStream &input) : IFFDecoder(input) { + +} + +PBMDecoder::~PBMDecoder() { + +} + + +  void decodeILBM(Common::ReadStream &input, Surface &surface, byte *&colors) {  	IFF_ID typeId;  	BMHD bitmapHeader; diff --git a/graphics/ilbm.h b/graphics/ilbm.h index c95dc3504b..7d1f06767b 100644 --- a/graphics/ilbm.h +++ b/graphics/ilbm.h @@ -26,6 +26,133 @@ namespace Graphics {  void decodeILBM(Common::ReadStream &input, Surface &surface, byte *&colors); + +typedef uint32 IFF_ID; + +struct Chunk { +	IFF_ID id; +	uint32 size; +	uint32 bytesRead; +	Common::ReadStream *_input; + +	Chunk(Common::ReadStream *input): _input(input) { +		size = bytesRead = 0; +	} + +	void incBytesRead(uint32 inc) { +		bytesRead += inc; +		if (bytesRead > size) { +			error("Chunk overead"); +		} +	} + +	void readHeader() { +		id = _input->readUint32BE(); +		size = _input->readUint32BE(); +		bytesRead = 0; +	} + +	bool eos() { +		return (size - bytesRead) == 0; +	} + +	void feed() { +		if (size % 2) { +			size++; +		} +		while (!_input->eos() && !eos()) { +			readByte(); +		} +	} + +	byte readByte() { +		incBytesRead(1); +		return _input->readByte(); +	} + +	int8 readSByte() { +		incBytesRead(1); +		return _input->readSByte(); +	} + +	uint16 readUint16() { +		incBytesRead(2); +		return _input->readUint16BE(); +	} + +	uint32 readUint32() { +		incBytesRead(4); +		return _input->readUint32BE(); +	} + +	int16 readSint16() { +		return (int16)readUint16(); +	} + +	int32 readSint32() { +		return (int32)readUint32(); +	} +}; + + +struct BMHD { +	uint16 width, height; +	uint16 x, y; +	byte depth; +	byte masking; +	byte pack; +	byte flags; +	uint16 transparentColor; +	byte xAspect, yAspect; +	uint16 pageWidth, pageHeight; +	BMHD() { +		memset(this, 0, sizeof(*this)); +	} +}; + + + +class IFFDecoder { + +protected: +	Chunk 	_formChunk; +	Chunk 	_chunk; + +	IFF_ID 	_typeId; +	BMHD 	_bitmapHeader; +	uint32 	_colorCount; + +	Surface *_surface; +	byte    *_colors; + +	virtual bool isTypeSupported(IFF_ID type) = 0; +	virtual void readBODY() = 0; + +	virtual void readBMHD(); +	virtual void readCMAP(); + +public: +	IFFDecoder(Common::ReadStream &input); +	virtual ~IFFDecoder(); + +	virtual void decode(Surface &surface, byte *&colors); + +}; + + + +class PBMDecoder : public IFFDecoder { + +protected: +	bool isTypeSupported(IFF_ID type); +	void readBody(); + +public: +	PBMDecoder(Common::ReadStream &input); +	~PBMDecoder(); + +}; +  }	// End of namespace Graphics  #endif  | 
