From 372ede7904581c868d33b3cf0ec2490cbbd774d7 Mon Sep 17 00:00:00 2001 From: Alyssa Milburn Date: Tue, 21 Dec 2010 18:16:37 +0000 Subject: MOHAWK: Support compound images (subimages) These are images embedded in the bitmap data of another image; they are used in CSTime and Zoombinis, at least. Thanks to clone2727 for helping me puzzle this out. svn-id: r54989 --- engines/mohawk/bitmap.cpp | 41 ++++++++++++++++++++++++++++++++++++++--- engines/mohawk/bitmap.h | 4 ++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/engines/mohawk/bitmap.cpp b/engines/mohawk/bitmap.cpp index d3d560b1a6..ac4f27619b 100644 --- a/engines/mohawk/bitmap.cpp +++ b/engines/mohawk/bitmap.cpp @@ -59,7 +59,7 @@ MohawkBitmap::MohawkBitmap() { MohawkBitmap::~MohawkBitmap() { } -MohawkSurface *MohawkBitmap::decodeImage(Common::SeekableReadStream *stream) { +void MohawkBitmap::decodeImageData(Common::SeekableReadStream *stream) { _data = stream; _header.colorTable.palette = NULL; @@ -90,15 +90,50 @@ MohawkSurface *MohawkBitmap::decodeImage(Common::SeekableReadStream *stream) { } } - Graphics::Surface *surface = createSurface(_header.width, _header.height); - unpackImage(); +} + +MohawkSurface *MohawkBitmap::decodeImage(Common::SeekableReadStream *stream) { + decodeImageData(stream); + + Graphics::Surface *surface = createSurface(_header.width, _header.height); drawImage(surface); delete _data; return new MohawkSurface(surface, _header.colorTable.palette); } +Common::Array MohawkBitmap::decodeImages(Common::SeekableReadStream *stream) { + decodeImageData(stream); + + // Some Mohawk games (CSTime, Zoombinis) store 'compound shapes' by + // packing several sub-images inside the data portion of an image. + // We take a copy of what we need (since it will be overwritten), + // and then decodeImage() all these sub-images. + Common::SeekableReadStream *data = _data; + int32 startPos = data->pos(); + uint16 count = _header.width; + + Common::Array offsets; + for (uint i = 0; i < count; i++) + offsets.push_back(data->readUint32BE()); + + Common::Array surfaces; + for (uint i = 0; i < count; i++) { + uint32 start = startPos + offsets[i] - 8; + uint32 end; + if (i != (uint)count - 1) + end = startPos + offsets[i + 1] - 8; + else + end = data->size(); + Common::SeekableSubReadStream *substream = new Common::SeekableSubReadStream(data, start, end); + surfaces.push_back(decodeImage(substream)); + } + + delete data; + return surfaces; +} + Graphics::Surface *MohawkBitmap::createSurface(uint16 width, uint16 height) { Graphics::Surface *surface = new Graphics::Surface(); byte bytesPerPixel = (getBitsPerPixel() <= 8) ? 1 : g_system->getScreenFormat().bytesPerPixel; diff --git a/engines/mohawk/bitmap.h b/engines/mohawk/bitmap.h index 6dd6b1115d..14b8e75327 100644 --- a/engines/mohawk/bitmap.h +++ b/engines/mohawk/bitmap.h @@ -30,6 +30,7 @@ #include "common/scummsys.h" #include "common/stream.h" +#include "common/array.h" #include "graphics/surface.h" namespace Mohawk { @@ -85,11 +86,14 @@ public: virtual ~MohawkBitmap(); virtual MohawkSurface *decodeImage(Common::SeekableReadStream *stream); + Common::Array decodeImages(Common::SeekableReadStream *stream); protected: BitmapHeader _header; virtual byte getBitsPerPixel(); + void decodeImageData(Common::SeekableReadStream *stream); + // The actual LZ decoder static Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream *stream, uint32 uncompressedSize); -- cgit v1.2.3