GOB: Implement LBM loading

svn-id: r55732
This commit is contained in:
Sven Hesse 2011-02-02 16:50:57 +00:00
parent 729be647a0
commit 63c6d4432c
2 changed files with 140 additions and 2 deletions

View File

@ -34,6 +34,105 @@
namespace Gob {
LBMLoader::LBMLoader(Common::SeekableReadStream &stream) : _parser(&stream),
_hasHeader(false), _palette(0), _image(0) {
}
bool LBMLoader::loadHeader(Graphics::BMHD &header) {
if (!readHeader())
return false;
header = _decoder._header;
return true;
}
bool LBMLoader::loadPalette(byte *palette) {
assert(!_palette);
assert(palette);
_palette = palette;
Common::Functor1Mem<Common::IFFChunk&, bool, LBMLoader> c(this, &LBMLoader::callbackPalette);
_parser.parse(c);
if (!_palette)
return false;
_palette = 0;
return true;
}
bool LBMLoader::loadImage(byte *image) {
assert(!_image);
assert(image);
if (!readHeader())
return false;
_image = image;
Common::Functor1Mem<Common::IFFChunk&, bool, LBMLoader> c(this, &LBMLoader::callbackImage);
_parser.parse(c);
if (!_image)
return false;
_image = 0;
return true;
}
bool LBMLoader::callbackHeader(Common::IFFChunk &chunk) {
if (chunk._type == ID_BMHD) {
if (chunk._size == sizeof(Graphics::BMHD)) {
_decoder.loadHeader(chunk._stream);
_hasHeader = true;
}
return true; // Stop the IFF parser
}
return false;
}
bool LBMLoader::callbackPalette(Common::IFFChunk &chunk) {
assert(_palette);
if (chunk._type == ID_CMAP) {
if (chunk._size == 768) {
if (chunk._stream->read(_palette, chunk._size) != chunk._size)
_palette = 0;
} else
_palette = 0;
return true; // Stop the IFF parser
}
return false;
}
bool LBMLoader::callbackImage(Common::IFFChunk &chunk) {
assert(_image);
if (chunk._type == ID_BODY) {
_decoder.loadBitmap(Graphics::ILBMDecoder::ILBM_UNPACK_PLANES, _image, chunk._stream);
return true;
}
return false;
}
bool LBMLoader::readHeader() {
if (_hasHeader)
return true;
Common::Functor1Mem<Common::IFFChunk&, bool, LBMLoader> c(this, &LBMLoader::callbackHeader);
_parser.parse(c);
return _hasHeader;
}
static void plotPixel(int x, int y, int color, void *data) {
Surface *dest = (Surface *)data;
@ -761,8 +860,19 @@ bool Surface::loadTGA(Common::SeekableReadStream &stream) {
}
bool Surface::loadLBM(Common::SeekableReadStream &stream) {
warning("TODO: Surface::loadLBM()");
return false;
LBMLoader loader(stream);
Graphics::BMHD header;
loader.loadHeader(header);
if (header.depth != 8)
// Only 8bpp LBMs supported for now
return false;
resize(header.width, header.height);
return loader.loadImage(_vidMem);
}
bool Surface::loadBRC(Common::SeekableReadStream &stream) {

View File

@ -29,6 +29,9 @@
#include "common/scummsys.h"
#include "common/ptr.h"
#include "common/rational.h"
#include "common/iff_container.h"
#include "graphics/iff.h"
namespace Common {
class SeekableReadStream;
@ -45,6 +48,31 @@ enum ImageType {
kImageTypeJPEG
};
class LBMLoader {
public:
LBMLoader(Common::SeekableReadStream &stream);
bool loadHeader (Graphics::BMHD &header);
bool loadPalette(byte *palette);
bool loadImage (byte *image);
private:
Common::IFFParser _parser;
bool _hasHeader;
Graphics::ILBMDecoder _decoder;
byte *_palette;
byte *_image;
bool callbackHeader (Common::IFFChunk &chunk);
bool callbackPalette(Common::IFFChunk &chunk);
bool callbackImage (Common::IFFChunk &chunk);
bool readHeader();
};
/** An iterator over a surface's image data, automatically handles different color depths. */
class Pixel {
public: