* Moved the updated IFF code from Parallaction to common/
* Updated Parallaction and SAGA to use the new decoder infrastructure. svn-id: r41465
This commit is contained in:
parent
b9017519fa
commit
36828287ad
12 changed files with 364 additions and 663 deletions
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/endian.h"
|
||||
#include "common/func.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/util.h"
|
||||
|
||||
|
@ -145,37 +146,57 @@ page 376) */
|
|||
char * ID2string(Common::IFF_ID id);
|
||||
|
||||
|
||||
class IFFChunk : public Common::ReadStream {
|
||||
/**
|
||||
* Represents a IFF chunk available to client code.
|
||||
*
|
||||
* Client code must *not* deallocate _stream when done.
|
||||
*/
|
||||
struct IFFChunk {
|
||||
Common::IFF_ID _type;
|
||||
uint32 _size;
|
||||
Common::ReadStream *_stream;
|
||||
|
||||
IFFChunk(Common::IFF_ID type, uint32 size, Common::ReadStream *stream) : _type(type), _size(size), _stream(stream) {
|
||||
assert(_stream);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Parser for IFF containers.
|
||||
*/
|
||||
class IFFParser {
|
||||
|
||||
/**
|
||||
* This private class implements IFF chunk navigation.
|
||||
*/
|
||||
class IFFChunkNav : public Common::ReadStream {
|
||||
protected:
|
||||
Common::ReadStream *_input;
|
||||
uint32 bytesRead;
|
||||
|
||||
uint32 _bytesRead;
|
||||
public:
|
||||
IFF_ID id;
|
||||
Common::IFF_ID id;
|
||||
uint32 size;
|
||||
|
||||
IFFChunk(Common::ReadStream *input): _input(input) {
|
||||
size = bytesRead = 0;
|
||||
IFFChunkNav() : _input(0) {
|
||||
}
|
||||
void setInputStream(Common::ReadStream *input) {
|
||||
_input = input;
|
||||
size = _bytesRead = 0;
|
||||
}
|
||||
|
||||
void incBytesRead(uint32 inc) {
|
||||
bytesRead += inc;
|
||||
if (bytesRead > size) {
|
||||
error("Chunk '%s' overread", ID2string(id));
|
||||
_bytesRead += inc;
|
||||
if (_bytesRead > size) {
|
||||
error("Chunk overread");
|
||||
}
|
||||
}
|
||||
|
||||
void readHeader() {
|
||||
id = _input->readUint32BE();
|
||||
size = _input->readUint32BE();
|
||||
bytesRead = 0;
|
||||
_bytesRead = 0;
|
||||
}
|
||||
|
||||
bool hasReadAll() const {
|
||||
return (size - bytesRead) == 0;
|
||||
return (size - _bytesRead) == 0;
|
||||
}
|
||||
|
||||
void feed() {
|
||||
if (size % 2) {
|
||||
size++;
|
||||
|
@ -184,7 +205,6 @@ public:
|
|||
readByte();
|
||||
}
|
||||
}
|
||||
|
||||
// Common::ReadStream implementation
|
||||
bool eos() const { return _input->eos(); }
|
||||
bool err() const { return _input->err(); }
|
||||
|
@ -194,41 +214,91 @@ public:
|
|||
incBytesRead(dataSize);
|
||||
return _input->read(dataPtr, dataSize);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class IFFParser {
|
||||
public:
|
||||
IFFParser(Common::ReadStream &input) : _formChunk(&input), _chunk(&input) {
|
||||
IFFChunkNav _formChunk; //!< The root chunk of the file.
|
||||
IFFChunkNav _chunk; //!< The current chunk.
|
||||
|
||||
Common::ReadStream *_stream;
|
||||
bool _disposeStream;
|
||||
|
||||
void setInputStream(Common::ReadStream *stream) {
|
||||
assert(stream);
|
||||
_formChunk.setInputStream(stream);
|
||||
_chunk.setInputStream(stream);
|
||||
|
||||
_formChunk.readHeader();
|
||||
if (_formChunk.id != ID_FORM) {
|
||||
error("IFFParser input is not a FORM type IFF file");
|
||||
}
|
||||
_typeId = _formChunk.readUint32BE();
|
||||
_formSize = _formChunk.size;
|
||||
_formType = _formChunk.readUint32BE();
|
||||
}
|
||||
|
||||
virtual ~IFFParser() {}
|
||||
public:
|
||||
IFFParser(Common::ReadStream *stream, bool disposeStream = false) : _stream(stream), _disposeStream(stream) {
|
||||
setInputStream(stream);
|
||||
}
|
||||
~IFFParser() {
|
||||
if (_disposeStream) {
|
||||
delete _stream;
|
||||
}
|
||||
_stream = 0;
|
||||
}
|
||||
|
||||
IFFChunk *nextChunk() {
|
||||
/**
|
||||
* Returns the IFF FORM type.
|
||||
* @return the IFF FORM type of the stream, or 0 if FORM header is not found.
|
||||
*/
|
||||
Common::IFF_ID getFORMType() const;
|
||||
|
||||
/**
|
||||
* Returns the size of the data.
|
||||
* @return the size of the data in file, or -1 if FORM header is not found.
|
||||
*/
|
||||
uint32 getFORMSize() const;
|
||||
|
||||
/**
|
||||
* Callback type for the parser.
|
||||
*/
|
||||
typedef Common::Functor1< IFFChunk&, bool > IFFCallback;
|
||||
|
||||
/**
|
||||
* Parse the IFF container, invoking the callback on each chunk encountered.
|
||||
* The callback can interrupt the parsing by returning 'true'.
|
||||
*/
|
||||
void parse(IFFCallback &callback) {
|
||||
bool stop;
|
||||
do {
|
||||
_chunk.feed();
|
||||
_formChunk.incBytesRead(_chunk.size);
|
||||
|
||||
if (_formChunk.hasReadAll())
|
||||
return 0;
|
||||
if (_formChunk.hasReadAll()) {
|
||||
break;
|
||||
}
|
||||
|
||||
_formChunk.incBytesRead(8);
|
||||
_chunk.readHeader();
|
||||
|
||||
return &_chunk;
|
||||
// invoke the callback
|
||||
Common::SubReadStream stream(&_chunk, _chunk.size);
|
||||
IFFChunk chunk(_chunk.id, _chunk.size, &stream);
|
||||
stop = callback(chunk);
|
||||
|
||||
// eats up all the remaining data in the chunk
|
||||
while (!stream.eos()) {
|
||||
stream.readByte();
|
||||
}
|
||||
|
||||
IFF_ID _typeId;
|
||||
} while (!stop);
|
||||
}
|
||||
|
||||
protected:
|
||||
IFFChunk _formChunk;
|
||||
IFFChunk _chunk;
|
||||
private:
|
||||
uint32 _formSize;
|
||||
Common::IFF_ID _formType;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Common
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,30 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include "parallaction/disk.h"
|
||||
#include "parallaction/graphics.h"
|
||||
#include "parallaction/iff.h"
|
||||
|
||||
namespace Parallaction {
|
||||
|
||||
|
@ -13,7 +37,7 @@ void ILBMLoader::setupBuffer(uint32 w, uint32 h) {
|
|||
assert(_surf);
|
||||
}
|
||||
_surf->create(w, h, 1);
|
||||
_mode = ILBMDecoder::ILBM_UNPACK_PLANES;
|
||||
_mode = Graphics::ILBMDecoder::ILBM_UNPACK_PLANES;
|
||||
_intBuffer = (byte*)_surf->pixels;
|
||||
break;
|
||||
|
||||
|
@ -23,7 +47,7 @@ void ILBMLoader::setupBuffer(uint32 w, uint32 h) {
|
|||
assert(_maskBuffer);
|
||||
}
|
||||
_maskBuffer->create(w, h);
|
||||
_mode = ILBMDecoder::ILBM_2_PACK_PLANES;
|
||||
_mode = Graphics::ILBMDecoder::ILBM_2_PACK_PLANES;
|
||||
_intBuffer = _maskBuffer->data;
|
||||
break;
|
||||
|
||||
|
@ -33,7 +57,7 @@ void ILBMLoader::setupBuffer(uint32 w, uint32 h) {
|
|||
assert(_pathBuffer);
|
||||
}
|
||||
_pathBuffer->create(w, h);
|
||||
_mode = ILBMDecoder::ILBM_1_PACK_PLANES;
|
||||
_mode = Graphics::ILBMDecoder::ILBM_1_PACK_PLANES;
|
||||
_intBuffer = _pathBuffer->data;
|
||||
break;
|
||||
|
||||
|
@ -43,7 +67,7 @@ void ILBMLoader::setupBuffer(uint32 w, uint32 h) {
|
|||
}
|
||||
}
|
||||
|
||||
bool ILBMLoader::callback(IFFChunk &chunk) {
|
||||
bool ILBMLoader::callback(Common::IFFChunk &chunk) {
|
||||
switch (chunk._type) {
|
||||
case ID_BMHD:
|
||||
_decoder.loadHeader(chunk._stream);
|
||||
|
@ -77,8 +101,8 @@ bool ILBMLoader::callback(IFFChunk &chunk) {
|
|||
}
|
||||
|
||||
void ILBMLoader::load(Common::ReadStream *in, bool disposeStream) {
|
||||
IFFParser parser(in, disposeStream);
|
||||
Common::Functor1Mem< IFFChunk&, bool, ILBMLoader > c(this, &ILBMLoader::callback);
|
||||
Common::IFFParser parser(in, disposeStream);
|
||||
Common::Functor1Mem< Common::IFFChunk&, bool, ILBMLoader > c(this, &ILBMLoader::callback);
|
||||
parser.parse(c);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "common/file.h"
|
||||
|
||||
#include "graphics/surface.h"
|
||||
#include "parallaction/iff.h"
|
||||
#include "graphics/iff.h"
|
||||
|
||||
|
||||
|
||||
|
@ -99,14 +99,14 @@ struct ILBMLoader {
|
|||
uint32 _mode;
|
||||
byte* _intBuffer;
|
||||
uint32 _numCRNG;
|
||||
ILBMDecoder _decoder;
|
||||
Graphics::ILBMDecoder _decoder;
|
||||
|
||||
ILBMLoader(uint32 bodyMode, byte *palette = 0, PaletteFxRange *crng = 0);
|
||||
ILBMLoader(Graphics::Surface *surf, byte *palette = 0, PaletteFxRange *crng = 0);
|
||||
ILBMLoader(MaskBuffer *buffer);
|
||||
ILBMLoader(PathBuffer *buffer);
|
||||
|
||||
bool callback(IFFChunk &chunk);
|
||||
bool callback(Common::IFFChunk &chunk);
|
||||
void setupBuffer(uint32 w, uint32 h);
|
||||
void load(Common::ReadStream *in, bool disposeStream = false);
|
||||
};
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "common/config-manager.h"
|
||||
#include "parallaction/parallaction.h"
|
||||
#include "parallaction/parser.h"
|
||||
#include "parallaction/iff.h"
|
||||
|
||||
|
||||
namespace Parallaction {
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "parallaction/iff.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "parallaction/parser.h"
|
||||
#include "parallaction/parallaction.h"
|
||||
|
|
|
@ -1,186 +0,0 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "common/iff_container.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/util.h"
|
||||
#include "parallaction/iff.h"
|
||||
|
||||
namespace Parallaction {
|
||||
|
||||
|
||||
void IFFParser::setInputStream(Common::ReadStream *stream) {
|
||||
assert(stream);
|
||||
_formChunk.setInputStream(stream);
|
||||
_chunk.setInputStream(stream);
|
||||
|
||||
_formChunk.readHeader();
|
||||
if (_formChunk.id != ID_FORM) {
|
||||
error("IFFParser input is not a FORM type IFF file");
|
||||
}
|
||||
_formSize = _formChunk.size;
|
||||
_formType = _formChunk.readUint32BE();
|
||||
}
|
||||
|
||||
uint32 IFFParser::getFORMSize() const {
|
||||
return _formSize;
|
||||
}
|
||||
|
||||
Common::IFF_ID IFFParser::getFORMType() const {
|
||||
return _formType;
|
||||
}
|
||||
|
||||
void IFFParser::parse(IFFCallback &callback) {
|
||||
bool stop;
|
||||
do {
|
||||
_chunk.feed();
|
||||
_formChunk.incBytesRead(_chunk.size);
|
||||
|
||||
if (_formChunk.hasReadAll()) {
|
||||
break;
|
||||
}
|
||||
|
||||
_formChunk.incBytesRead(8);
|
||||
_chunk.readHeader();
|
||||
|
||||
// invoke the callback
|
||||
Common::SubReadStream stream(&_chunk, _chunk.size);
|
||||
IFFChunk chunk(_chunk.id, _chunk.size, &stream);
|
||||
stop = callback(chunk);
|
||||
|
||||
// eats up all the remaining data in the chunk
|
||||
while (!stream.eos()) {
|
||||
stream.readByte();
|
||||
}
|
||||
|
||||
|
||||
} while (!stop);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ILBMDecoder::loadHeader(Common::ReadStream *stream) {
|
||||
assert(stream);
|
||||
stream->read(&_header, sizeof(_header));
|
||||
_header.width = FROM_BE_16(_header.width);
|
||||
_header.height = FROM_BE_16(_header.height);
|
||||
_header.x = FROM_BE_16(_header.x);
|
||||
_header.y = FROM_BE_16(_header.y);
|
||||
_header.transparentColor = FROM_BE_16(_header.transparentColor);
|
||||
_header.pageWidth = FROM_BE_16(_header.pageWidth);
|
||||
_header.pageHeight = FROM_BE_16(_header.pageHeight);
|
||||
}
|
||||
|
||||
void ILBMDecoder::loadBitmap(uint32 mode, byte *buffer, Common::ReadStream *stream) {
|
||||
assert(stream);
|
||||
uint32 numPlanes = MIN(mode & ILBM_UNPACK_PLANES, (uint32)_header.depth);
|
||||
assert(numPlanes == 1 || numPlanes == 2 || numPlanes == 3 || numPlanes == 4 || numPlanes == 5 || numPlanes == 8);
|
||||
|
||||
bool packPixels = (mode & ILBM_PACK_PLANES) != 0;
|
||||
if (numPlanes != 1 && numPlanes != 2 && numPlanes != 4) {
|
||||
packPixels = false;
|
||||
}
|
||||
|
||||
uint32 outPitch = _header.width;
|
||||
if (packPixels) {
|
||||
outPitch /= (8 / numPlanes);
|
||||
}
|
||||
byte *out = buffer;
|
||||
|
||||
switch (_header.pack) {
|
||||
case 1: { // PackBits compressed bitmap
|
||||
Graphics::PackBitsReadStream packStream(*stream);
|
||||
|
||||
// setup a buffer to hold enough data to build a line in the output
|
||||
uint32 scanlineWidth = ((_header.width + 15)/16) << 1;
|
||||
byte *scanline = new byte[scanlineWidth * _header.depth];
|
||||
|
||||
for (uint i = 0; i < _header.height; ++i) {
|
||||
byte *s = scanline;
|
||||
for (uint32 j = 0; j < _header.depth; ++j) {
|
||||
packStream.read(s, scanlineWidth);
|
||||
s += scanlineWidth;
|
||||
}
|
||||
|
||||
planarToChunky(out, outPitch, scanline, scanlineWidth, numPlanes, packPixels);
|
||||
out += outPitch;
|
||||
}
|
||||
|
||||
delete []scanline;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// implement other compression types here!
|
||||
error("only RLE compressed ILBM files are supported");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ILBMDecoder::planarToChunky(byte *out, uint32 outPitch, byte *in, uint32 inWidth, uint32 nPlanes, bool packPlanes) {
|
||||
byte pix, ofs, bit;
|
||||
byte *s;
|
||||
|
||||
uint32 pixels = outPitch;
|
||||
if (packPlanes) {
|
||||
pixels *= (8 / nPlanes);
|
||||
}
|
||||
|
||||
for (uint32 x = 0; x < pixels; ++x) {
|
||||
|
||||
pix = 0;
|
||||
ofs = x >> 3;
|
||||
bit = 0x80 >> (x & 7);
|
||||
|
||||
// first build a pixel by scanning all the usable planes in the input
|
||||
s = in;
|
||||
for (uint32 plane = 0; plane < nPlanes; ++plane) {
|
||||
if (s[ofs] & bit) {
|
||||
pix |= (1 << plane);
|
||||
}
|
||||
s += inWidth;
|
||||
}
|
||||
|
||||
|
||||
// then output the pixel according to the requested packing
|
||||
if (!packPlanes) {
|
||||
out[x] = pix;
|
||||
} else
|
||||
if (nPlanes == 1) {
|
||||
out[x/8] |= (pix << (x & 7));
|
||||
} else
|
||||
if (nPlanes == 2) {
|
||||
out[x/4] |= (pix << ((x & 3) << 1));
|
||||
} else
|
||||
if (nPlanes == 4) {
|
||||
out[x/2] |= (pix << ((x & 1) << 2));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace Parallaction
|
|
@ -1,206 +0,0 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PARALLACTION_IFF_H
|
||||
#define PARALLACTION_IFF_H
|
||||
|
||||
#include "common/stream.h"
|
||||
#include "common/func.h"
|
||||
#include "common/iff_container.h" // for IFF chunk names
|
||||
#include "graphics/iff.h" // for BMHD
|
||||
|
||||
|
||||
namespace Parallaction {
|
||||
|
||||
/**
|
||||
* Represents a IFF chunk available to client code.
|
||||
*
|
||||
* Client code must *not* deallocate _stream when done.
|
||||
*/
|
||||
struct IFFChunk {
|
||||
Common::IFF_ID _type;
|
||||
uint32 _size;
|
||||
Common::ReadStream *_stream;
|
||||
|
||||
IFFChunk(Common::IFF_ID type, uint32 size, Common::ReadStream *stream) : _type(type), _size(size), _stream(stream) {
|
||||
assert(_stream);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Parser for IFF containers.
|
||||
*/
|
||||
class IFFParser {
|
||||
|
||||
/**
|
||||
* This private class implements IFF chunk navigation.
|
||||
*/
|
||||
class IFFChunkNav : public Common::ReadStream {
|
||||
protected:
|
||||
Common::ReadStream *_input;
|
||||
uint32 _bytesRead;
|
||||
public:
|
||||
Common::IFF_ID id;
|
||||
uint32 size;
|
||||
|
||||
IFFChunkNav() : _input(0) {
|
||||
}
|
||||
void setInputStream(Common::ReadStream *input) {
|
||||
_input = input;
|
||||
size = _bytesRead = 0;
|
||||
}
|
||||
void incBytesRead(uint32 inc) {
|
||||
_bytesRead += inc;
|
||||
if (_bytesRead > size) {
|
||||
error("Chunk overread");
|
||||
}
|
||||
}
|
||||
void readHeader() {
|
||||
id = _input->readUint32BE();
|
||||
size = _input->readUint32BE();
|
||||
_bytesRead = 0;
|
||||
}
|
||||
bool hasReadAll() const {
|
||||
return (size - _bytesRead) == 0;
|
||||
}
|
||||
void feed() {
|
||||
if (size % 2) {
|
||||
size++;
|
||||
}
|
||||
while (!hasReadAll()) {
|
||||
readByte();
|
||||
}
|
||||
}
|
||||
// Common::ReadStream implementation
|
||||
bool eos() const { return _input->eos(); }
|
||||
bool err() const { return _input->err(); }
|
||||
void clearErr() { _input->clearErr(); }
|
||||
|
||||
uint32 read(void *dataPtr, uint32 dataSize) {
|
||||
incBytesRead(dataSize);
|
||||
return _input->read(dataPtr, dataSize);
|
||||
}
|
||||
};
|
||||
|
||||
IFFChunkNav _formChunk; //!< The root chunk of the file.
|
||||
IFFChunkNav _chunk; //!< The current chunk.
|
||||
|
||||
Common::ReadStream *_stream;
|
||||
bool _disposeStream;
|
||||
|
||||
void setInputStream(Common::ReadStream *stream);
|
||||
|
||||
public:
|
||||
IFFParser(Common::ReadStream *stream, bool disposeStream = false) : _stream(stream), _disposeStream(stream) {
|
||||
setInputStream(stream);
|
||||
}
|
||||
~IFFParser() {
|
||||
if (_disposeStream) {
|
||||
delete _stream;
|
||||
}
|
||||
_stream = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IFF FORM type.
|
||||
* @return the IFF FORM type of the stream, or 0 if FORM header is not found.
|
||||
*/
|
||||
Common::IFF_ID getFORMType() const;
|
||||
|
||||
/**
|
||||
* Returns the size of the data.
|
||||
* @return the size of the data in file, or -1 if FORM header is not found.
|
||||
*/
|
||||
uint32 getFORMSize() const;
|
||||
|
||||
/**
|
||||
* Callback type for the parser.
|
||||
*/
|
||||
typedef Common::Functor1< IFFChunk&, bool > IFFCallback;
|
||||
|
||||
/**
|
||||
* Parse the IFF container, invoking the callback on each chunk encountered.
|
||||
* The callback can interrupt the parsing by returning 'true'.
|
||||
*/
|
||||
void parse(IFFCallback &callback);
|
||||
|
||||
private:
|
||||
uint32 _formSize;
|
||||
Common::IFF_ID _formType;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
struct ILBMDecoder {
|
||||
/**
|
||||
* ILBM header data, necessary for loadBitmap()
|
||||
*/
|
||||
Graphics::BMHD _header;
|
||||
|
||||
/**
|
||||
* Available decoding modes for loadBitmap().
|
||||
*/
|
||||
enum {
|
||||
ILBM_UNPACK_PLANES = 0xFF, //!< Decode all bitplanes, and map 1 pixel to 1 byte.
|
||||
ILBM_PACK_PLANES = 0x100, //!< Request unpacking, used as a mask with below options.
|
||||
|
||||
ILBM_1_PLANES = 1, //!< Decode only the first bitplane, don't pack.
|
||||
ILBM_1_PACK_PLANES = ILBM_1_PLANES | ILBM_PACK_PLANES, //!< Decode only the first bitplane, pack 8 pixels in 1 byte.
|
||||
ILBM_2_PLANES = 2, //!< Decode first 2 bitplanes, don't pack.
|
||||
ILBM_2_PACK_PLANES = ILBM_2_PLANES | ILBM_PACK_PLANES, //!< Decode first 2 bitplanes, pack 4 pixels in 1 byte.
|
||||
ILBM_3_PLANES = 3, //!< Decode first 3 bitplanes, don't pack.
|
||||
ILBM_4_PLANES = 4, //!< Decode first 4 bitplanes, don't pack.
|
||||
ILBM_4_PACK_PLANES = ILBM_4_PLANES | ILBM_PACK_PLANES, //!< Decode first 4 bitplanes, pack 2 pixels in 1 byte.
|
||||
ILBM_5_PLANES = 5, //!< Decode first 5 bitplanes, don't pack.
|
||||
ILBM_8_PLANES = 8 //!< Decode all 8 bitplanes.
|
||||
};
|
||||
|
||||
/**
|
||||
* Fills the _header member from the given stream.
|
||||
*/
|
||||
void loadHeader(Common::ReadStream *stream);
|
||||
|
||||
/**
|
||||
* Loads and unpacks the ILBM bitmap data from the stream into the buffer.
|
||||
* The functions assumes the buffer is large enough to contain all data.
|
||||
* The caller controls how data should be packed by choosing mode from
|
||||
* the enum above.
|
||||
*/
|
||||
void loadBitmap(uint32 mode, byte *buffer, Common::ReadStream *stream);
|
||||
|
||||
/**
|
||||
* Converts from bitplanar to chunky representation. Intended for internal
|
||||
* usage, but you can be (ab)use it from client code if you know what you
|
||||
* are doing.
|
||||
*/
|
||||
void planarToChunky(byte *out, uint32 width, byte *in, uint32 planeWidth, uint32 nPlanes, bool packPlanes);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -19,7 +19,6 @@ MODULE_OBJS := \
|
|||
gui.o \
|
||||
gui_br.o \
|
||||
gui_ns.o \
|
||||
iff.o \
|
||||
input.o \
|
||||
inventory.o \
|
||||
objects.o \
|
||||
|
|
|
@ -472,7 +472,7 @@ void Scene::changeScene(int16 sceneNumber, int actorsEntrance, SceneTransitionTy
|
|||
for (int i = 0; i < ARRAYSIZE(sceneSubstitutes); i++) {
|
||||
if (sceneSubstitutes[i].sceneId == sceneNumber) {
|
||||
Surface bbmBuffer;
|
||||
byte *pal, *colors;
|
||||
byte *pal, colors[768];
|
||||
Common::File file;
|
||||
Rect rect;
|
||||
PalEntry cPal[PAL_ENTRIES];
|
||||
|
@ -480,8 +480,8 @@ void Scene::changeScene(int16 sceneNumber, int actorsEntrance, SceneTransitionTy
|
|||
_vm->_interface->setMode(kPanelSceneSubstitute);
|
||||
|
||||
if (file.open(sceneSubstitutes[i].image)) {
|
||||
Graphics::decodePBM(file, bbmBuffer, pal);
|
||||
colors = pal;
|
||||
Graphics::decodePBM(file, bbmBuffer, colors);
|
||||
pal = colors;
|
||||
rect.setWidth(bbmBuffer.w);
|
||||
rect.setHeight(bbmBuffer.h);
|
||||
_vm->_gfx->drawRegion(rect, (const byte*)bbmBuffer.pixels);
|
||||
|
@ -490,7 +490,6 @@ void Scene::changeScene(int16 sceneNumber, int actorsEntrance, SceneTransitionTy
|
|||
cPal[j].green = *pal++;
|
||||
cPal[j].blue = *pal++;
|
||||
}
|
||||
free(colors);
|
||||
_vm->_gfx->setPalette(cPal);
|
||||
|
||||
}
|
||||
|
|
262
graphics/iff.cpp
262
graphics/iff.cpp
|
@ -48,191 +48,176 @@ char *ID2string(Common::IFF_ID id) {
|
|||
|
||||
namespace Graphics {
|
||||
|
||||
|
||||
void fillBMHD(BMHD &bitmapHeader, Common::ReadStream &stream) {
|
||||
|
||||
bitmapHeader.width = stream.readUint16BE();
|
||||
bitmapHeader.height = stream.readUint16BE();
|
||||
bitmapHeader.x = stream.readUint16BE();
|
||||
bitmapHeader.y = stream.readUint16BE();
|
||||
bitmapHeader.depth = stream.readByte();
|
||||
bitmapHeader.masking = stream.readByte();
|
||||
bitmapHeader.pack = stream.readByte();
|
||||
bitmapHeader.flags = stream.readByte();
|
||||
bitmapHeader.transparentColor = stream.readUint16BE();
|
||||
bitmapHeader.xAspect = stream.readByte();
|
||||
bitmapHeader.yAspect = stream.readByte();
|
||||
bitmapHeader.pageWidth = stream.readUint16BE();
|
||||
bitmapHeader.pageHeight = stream.readUint16BE();
|
||||
|
||||
void BMHD::load(Common::ReadStream *stream) {
|
||||
assert(stream);
|
||||
stream->read(this, sizeof(BMHD));
|
||||
width = FROM_BE_16(width);
|
||||
height = FROM_BE_16(height);
|
||||
x = FROM_BE_16(x);
|
||||
y = FROM_BE_16(y);
|
||||
transparentColor = FROM_BE_16(transparentColor);
|
||||
pageWidth = FROM_BE_16(pageWidth);
|
||||
pageHeight = FROM_BE_16(pageHeight);
|
||||
}
|
||||
|
||||
|
||||
ILBMDecoder::ILBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors) : IFFParser(input), _surface(&surface), _colors(&colors) {
|
||||
if (_typeId != ID_ILBM)
|
||||
error("unsupported IFF subtype '%s'", Common::ID2string(_typeId));
|
||||
void ILBMDecoder::loadHeader(Common::ReadStream *stream) {
|
||||
_header.load(stream);
|
||||
}
|
||||
|
||||
void ILBMDecoder::decode() {
|
||||
void ILBMDecoder::loadBitmap(uint32 mode, byte *buffer, Common::ReadStream *stream) {
|
||||
assert(stream);
|
||||
uint32 numPlanes = MIN(mode & ILBM_UNPACK_PLANES, (uint32)_header.depth);
|
||||
assert(numPlanes == 1 || numPlanes == 2 || numPlanes == 3 || numPlanes == 4 || numPlanes == 5 || numPlanes == 8);
|
||||
|
||||
Common::IFFChunk *chunk;
|
||||
while ((chunk = nextChunk()) != 0) {
|
||||
switch (chunk->id) {
|
||||
case ID_BMHD:
|
||||
readBMHD(*chunk);
|
||||
bool packPixels = (mode & ILBM_PACK_PLANES) != 0;
|
||||
if (numPlanes != 1 && numPlanes != 2 && numPlanes != 4) {
|
||||
packPixels = false;
|
||||
}
|
||||
|
||||
uint32 outPitch = _header.width;
|
||||
if (packPixels) {
|
||||
outPitch /= (8 / numPlanes);
|
||||
}
|
||||
byte *out = buffer;
|
||||
|
||||
switch (_header.pack) {
|
||||
case 1: { // PackBits compressed bitmap
|
||||
Graphics::PackBitsReadStream packStream(*stream);
|
||||
|
||||
// setup a buffer to hold enough data to build a line in the output
|
||||
uint32 scanlineWidth = ((_header.width + 15)/16) << 1;
|
||||
byte *scanline = new byte[scanlineWidth * _header.depth];
|
||||
|
||||
for (uint i = 0; i < _header.height; ++i) {
|
||||
byte *s = scanline;
|
||||
for (uint32 j = 0; j < _header.depth; ++j) {
|
||||
packStream.read(s, scanlineWidth);
|
||||
s += scanlineWidth;
|
||||
}
|
||||
|
||||
planarToChunky(out, outPitch, scanline, scanlineWidth, numPlanes, packPixels);
|
||||
out += outPitch;
|
||||
}
|
||||
|
||||
delete []scanline;
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_CMAP:
|
||||
readCMAP(*chunk);
|
||||
break;
|
||||
|
||||
case ID_BODY:
|
||||
readBODY(*chunk);
|
||||
default:
|
||||
// implement other compression types here!
|
||||
error("only RLE compressed ILBM files are supported");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
void ILBMDecoder::planarToChunky(byte *out, uint32 outPitch, byte *in, uint32 inWidth, uint32 nPlanes, bool packPlanes) {
|
||||
byte pix, ofs, bit;
|
||||
byte *s;
|
||||
|
||||
uint32 pixels = outPitch;
|
||||
if (packPlanes) {
|
||||
pixels *= (8 / nPlanes);
|
||||
}
|
||||
|
||||
void ILBMDecoder::readBMHD(Common::IFFChunk &chunk) {
|
||||
for (uint32 x = 0; x < pixels; ++x) {
|
||||
|
||||
fillBMHD(_bitmapHeader, chunk);
|
||||
|
||||
_colorCount = 1 << _bitmapHeader.depth;
|
||||
*_colors = (byte*)malloc(sizeof(**_colors) * _colorCount * 3);
|
||||
_surface->create(_bitmapHeader.width, _bitmapHeader.height, 1);
|
||||
pix = 0;
|
||||
ofs = x >> 3;
|
||||
bit = 0x80 >> (x & 7);
|
||||
|
||||
// first build a pixel by scanning all the usable planes in the input
|
||||
s = in;
|
||||
for (uint32 plane = 0; plane < nPlanes; ++plane) {
|
||||
if (s[ofs] & bit) {
|
||||
pix |= (1 << plane);
|
||||
}
|
||||
s += inWidth;
|
||||
}
|
||||
|
||||
void ILBMDecoder::readCMAP(Common::IFFChunk &chunk) {
|
||||
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();
|
||||
|
||||
// then output the pixel according to the requested packing
|
||||
if (!packPlanes) {
|
||||
out[x] = pix;
|
||||
} else
|
||||
if (nPlanes == 1) {
|
||||
out[x/8] |= (pix << (x & 7));
|
||||
} else
|
||||
if (nPlanes == 2) {
|
||||
out[x/4] |= (pix << ((x & 3) << 1));
|
||||
} else
|
||||
if (nPlanes == 4) {
|
||||
out[x/2] |= (pix << ((x & 1) << 2));
|
||||
}
|
||||
}
|
||||
|
||||
void ILBMDecoder::readBODY(Common::IFFChunk& chunk) {
|
||||
}
|
||||
|
||||
switch (_bitmapHeader.pack) {
|
||||
|
||||
void PBMDecoder::loadHeader(Common::ReadStream *stream) {
|
||||
_header.load(stream);
|
||||
}
|
||||
|
||||
|
||||
void PBMDecoder::loadBitmap(byte *buffer, Common::ReadStream *stream) {
|
||||
uint32 outSize = _header.width * _header.height;
|
||||
|
||||
switch (_header.pack) {
|
||||
case 0:
|
||||
error("unpacked ILBM files are not supported");
|
||||
stream->read(buffer, outSize);
|
||||
break;
|
||||
|
||||
case 1: {
|
||||
uint32 scanWidth = (_bitmapHeader.width + 7) >> 3;
|
||||
byte *scan = (byte*)malloc(scanWidth);
|
||||
byte *out = (byte*)_surface->pixels;
|
||||
|
||||
PackBitsReadStream stream(chunk);
|
||||
|
||||
for (uint32 i = 0; i < _bitmapHeader.height; i++) {
|
||||
for (uint32 j = 0; j < _bitmapHeader.depth; j++) {
|
||||
stream.read(scan, scanWidth);
|
||||
fillPlane(out, scan, scanWidth, j);
|
||||
}
|
||||
|
||||
out += _bitmapHeader.width;
|
||||
}
|
||||
free(scan);
|
||||
PackBitsReadStream packStream(*stream);
|
||||
packStream.read(buffer, outSize);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ILBMDecoder::fillPlane(byte *out, byte* buf, uint32 width, uint32 plane) {
|
||||
|
||||
byte src, idx, set;
|
||||
byte mask = 1 << plane;
|
||||
struct PBMLoader {
|
||||
PBMDecoder _decoder;
|
||||
Surface *_surface;
|
||||
byte *_colors;
|
||||
|
||||
for (uint32 j = 0; j < _bitmapHeader.width; j++) {
|
||||
src = buf[j >> 3];
|
||||
idx = 7 - (j & 7);
|
||||
set = src & (1 << idx);
|
||||
|
||||
if (set)
|
||||
out[j] |= mask;
|
||||
void load(Common::ReadStream &input, Surface &surface, byte *&colors) {
|
||||
_surface = &surface;
|
||||
_colors = colors;
|
||||
Common::IFFParser parser(&input);
|
||||
Common::Functor1Mem< Common::IFFChunk&, bool, PBMLoader > c(this, &PBMLoader::callback);
|
||||
parser.parse(c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PBMDecoder::PBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors) : IFFParser(input), _surface(&surface), _colors(&colors) {
|
||||
if (_typeId != ID_PBM)
|
||||
error("unsupported IFF subtype '%s'", Common::ID2string(_typeId));
|
||||
}
|
||||
|
||||
void PBMDecoder::decode() {
|
||||
|
||||
Common::IFFChunk *chunk;
|
||||
while ((chunk = nextChunk()) != 0) {
|
||||
switch (chunk->id) {
|
||||
bool callback(Common::IFFChunk &chunk) {
|
||||
switch (chunk._type) {
|
||||
case ID_BMHD:
|
||||
readBMHD(*chunk);
|
||||
_decoder.loadHeader(chunk._stream);
|
||||
break;
|
||||
|
||||
case ID_CMAP:
|
||||
readCMAP(*chunk);
|
||||
if (_colors) {
|
||||
chunk._stream->read(_colors, chunk._size);
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_BODY:
|
||||
readBODY(*chunk);
|
||||
break;
|
||||
if (_surface) {
|
||||
_surface->create(_decoder._header.width, _decoder._header.height, 1);
|
||||
_decoder.loadBitmap((byte*)_surface->pixels, chunk._stream);
|
||||
}
|
||||
return true; // stop the parser
|
||||
}
|
||||
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void PBMDecoder::readBMHD(Common::IFFChunk &chunk) {
|
||||
|
||||
fillBMHD(_bitmapHeader, chunk);
|
||||
|
||||
_colorCount = 1 << _bitmapHeader.depth;
|
||||
*_colors = (byte*)malloc(sizeof(**_colors) * _colorCount * 3);
|
||||
_surface->create(_bitmapHeader.width, _bitmapHeader.height, 1);
|
||||
|
||||
void decodePBM(Common::ReadStream &input, Surface &surface, byte *colors) {
|
||||
PBMLoader loader;
|
||||
loader.load(input, surface, colors);
|
||||
}
|
||||
|
||||
void PBMDecoder::readCMAP(Common::IFFChunk &chunk) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
void PBMDecoder::readBODY(Common::IFFChunk& chunk) {
|
||||
|
||||
uint si = 0;
|
||||
|
||||
switch (_bitmapHeader.pack) {
|
||||
case 0:
|
||||
while (!chunk.hasReadAll()) {
|
||||
((byte*)_surface->pixels)[si++] = chunk.readByte();
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: {
|
||||
PackBitsReadStream stream(chunk);
|
||||
stream.read((byte*)_surface->pixels, _surface->w * _surface->h);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -282,9 +267,4 @@ uint32 PackBitsReadStream::read(void *dataPtr, uint32 dataSize) {
|
|||
}
|
||||
|
||||
|
||||
void decodePBM(Common::ReadStream &input, Surface &surface, byte *&colors) {
|
||||
PBMDecoder decoder(input, surface, colors);
|
||||
decoder.decode();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,55 +52,80 @@ struct BMHD {
|
|||
BMHD() {
|
||||
memset(this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
void load(Common::ReadStream *stream);
|
||||
};
|
||||
|
||||
|
||||
// handles ILBM subtype of IFF FORM files
|
||||
//
|
||||
class ILBMDecoder : public Common::IFFParser {
|
||||
struct ILBMDecoder {
|
||||
/**
|
||||
* ILBM header data, necessary for loadBitmap()
|
||||
*/
|
||||
Graphics::BMHD _header;
|
||||
|
||||
protected:
|
||||
void readBMHD(Common::IFFChunk &chunk);
|
||||
void readCMAP(Common::IFFChunk &chunk);
|
||||
void readBODY(Common::IFFChunk &chunk);
|
||||
/**
|
||||
* Available decoding modes for loadBitmap().
|
||||
*/
|
||||
enum {
|
||||
ILBM_UNPACK_PLANES = 0xFF, //!< Decode all bitplanes, and map 1 pixel to 1 byte.
|
||||
ILBM_PACK_PLANES = 0x100, //!< Request unpacking, used as a mask with below options.
|
||||
|
||||
BMHD _bitmapHeader;
|
||||
uint32 _colorCount;
|
||||
|
||||
Surface *_surface;
|
||||
byte **_colors;
|
||||
|
||||
void fillPlane(byte *out, byte* buf, uint32 width, uint32 plane);
|
||||
|
||||
public:
|
||||
ILBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors);
|
||||
virtual ~ILBMDecoder() { }
|
||||
void decode();
|
||||
ILBM_1_PLANES = 1, //!< Decode only the first bitplane, don't pack.
|
||||
ILBM_1_PACK_PLANES = ILBM_1_PLANES | ILBM_PACK_PLANES, //!< Decode only the first bitplane, pack 8 pixels in 1 byte.
|
||||
ILBM_2_PLANES = 2, //!< Decode first 2 bitplanes, don't pack.
|
||||
ILBM_2_PACK_PLANES = ILBM_2_PLANES | ILBM_PACK_PLANES, //!< Decode first 2 bitplanes, pack 4 pixels in 1 byte.
|
||||
ILBM_3_PLANES = 3, //!< Decode first 3 bitplanes, don't pack.
|
||||
ILBM_4_PLANES = 4, //!< Decode first 4 bitplanes, don't pack.
|
||||
ILBM_4_PACK_PLANES = ILBM_4_PLANES | ILBM_PACK_PLANES, //!< Decode first 4 bitplanes, pack 2 pixels in 1 byte.
|
||||
ILBM_5_PLANES = 5, //!< Decode first 5 bitplanes, don't pack.
|
||||
ILBM_8_PLANES = 8 //!< Decode all 8 bitplanes.
|
||||
};
|
||||
|
||||
/**
|
||||
* Fills the _header member from the given stream.
|
||||
*/
|
||||
void loadHeader(Common::ReadStream *stream);
|
||||
|
||||
/**
|
||||
* Loads and unpacks the ILBM bitmap data from the stream into the buffer.
|
||||
* The functions assumes the buffer is large enough to contain all data.
|
||||
* The caller controls how data should be packed by choosing mode from
|
||||
* the enum above.
|
||||
*/
|
||||
void loadBitmap(uint32 mode, byte *buffer, Common::ReadStream *stream);
|
||||
|
||||
/**
|
||||
* Converts from bitplanar to chunky representation. Intended for internal
|
||||
* usage, but you can be (ab)use it from client code if you know what you
|
||||
* are doing.
|
||||
*/
|
||||
void planarToChunky(byte *out, uint32 width, byte *in, uint32 planeWidth, uint32 nPlanes, bool packPlanes);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// handles PBM subtype of IFF FORM files
|
||||
//
|
||||
class PBMDecoder : public Common::IFFParser {
|
||||
struct PBMDecoder {
|
||||
/**
|
||||
* PBM header data, necessary for loadBitmap()
|
||||
*/
|
||||
Graphics::BMHD _header;
|
||||
|
||||
protected:
|
||||
void readBMHD(Common::IFFChunk &chunk);
|
||||
void readCMAP(Common::IFFChunk &chunk);
|
||||
void readBODY(Common::IFFChunk &chunk);
|
||||
/**
|
||||
* Fills the _header member from the given stream.
|
||||
*/
|
||||
void loadHeader(Common::ReadStream *stream);
|
||||
|
||||
BMHD _bitmapHeader;
|
||||
uint32 _colorCount;
|
||||
|
||||
Surface *_surface;
|
||||
byte **_colors;
|
||||
|
||||
public:
|
||||
PBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors);
|
||||
virtual ~PBMDecoder() { }
|
||||
void decode();
|
||||
/**
|
||||
* Loads and unpacks the PBM bitmap data from the stream into the buffer.
|
||||
* The functions assumes the buffer is large enough to contain all data.
|
||||
*/
|
||||
void loadBitmap(byte *buffer, Common::ReadStream *stream);
|
||||
};
|
||||
|
||||
void decodePBM(Common::ReadStream &input, Surface &surface, byte *&colors);
|
||||
void decodePBM(Common::ReadStream &input, Surface &surface, byte *colors);
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -47,24 +47,22 @@ struct A8SVXLoader {
|
|||
uint32 _dataSize;
|
||||
|
||||
void load(Common::ReadStream &input) {
|
||||
Common::IFFParser parser(input);
|
||||
Common::IFFChunk *chunk;
|
||||
while (chunk = parser.nextChunk()) {
|
||||
callback(*chunk);
|
||||
}
|
||||
Common::IFFParser parser(&input);
|
||||
Common::Functor1Mem< Common::IFFChunk&, bool, A8SVXLoader > c(this, &A8SVXLoader::callback);
|
||||
parser.parse(c);
|
||||
}
|
||||
|
||||
bool callback(Common::IFFChunk &chunk) {
|
||||
switch (chunk.id) {
|
||||
switch (chunk._type) {
|
||||
case ID_VHDR:
|
||||
_header.load(chunk);
|
||||
_header.load(*chunk._stream);
|
||||
break;
|
||||
|
||||
case ID_BODY:
|
||||
_dataSize = chunk.size;
|
||||
_dataSize = chunk._size;
|
||||
_data = (int8*)malloc(_dataSize);
|
||||
assert(_data);
|
||||
loadData(&chunk);
|
||||
loadData(chunk._stream);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue