* Improved ILBMDecoder to also handle files with width non divisible by 8.

* Changed PackBitsReadStream to discard padding bytes on ditto files.

svn-id: r39410
This commit is contained in:
Nicola Mettifogo 2009-03-15 06:20:52 +00:00
parent a6497584cc
commit cbf9996abb
2 changed files with 34 additions and 76 deletions

View file

@ -124,14 +124,13 @@ void ILBMDecoder::readBODY(Common::IFFChunk& chunk) {
break; break;
case 1: { case 1: {
uint32 scanWidth = _bitmapHeader.width >> 3; uint32 scanWidth = (_bitmapHeader.width + 7) >> 3;
byte *scan = (byte*)malloc(scanWidth); byte *scan = (byte*)malloc(scanWidth);
byte *out = (byte*)_surface->pixels; byte *out = (byte*)_surface->pixels;
PackBitsReadStream stream(chunk); PackBitsReadStream stream(chunk);
for (uint32 i = 0; i < _bitmapHeader.height; i++) { for (uint32 i = 0; i < _bitmapHeader.height; i++) {
for (uint32 j = 0; j < _bitmapHeader.depth; j++) { for (uint32 j = 0; j < _bitmapHeader.depth; j++) {
stream.read(scan, scanWidth); stream.read(scan, scanWidth);
fillPlane(out, scan, scanWidth, j); fillPlane(out, scan, scanWidth, j);
@ -237,79 +236,49 @@ void PBMDecoder::readBODY(Common::IFFChunk& chunk) {
PackBitsReadStream::PackBitsReadStream(Common::ReadStream &input) : _input(&input) {
PackBitsReadStream::PackBitsReadStream(Common::ReadStream &input) : _input(&input), _wStoragePos(_storage), _rStoragePos(_storage) {
} }
PackBitsReadStream::~PackBitsReadStream() { PackBitsReadStream::~PackBitsReadStream() {
} }
bool PackBitsReadStream::eos() const { bool PackBitsReadStream::eos() const {
//FIXME: eos definition needs to be changed in parallaction engine return _input->eos();
// which is the only place where this class is used
return _input->eos() && (_rStoragePos == _wStoragePos);
} }
uint32 PackBitsReadStream::read(void *dataPtr, uint32 dataSize) { uint32 PackBitsReadStream::read(void *dataPtr, uint32 dataSize) {
_out = (byte*)dataPtr; byte *out = (byte*)dataPtr;
_outEnd = _out + dataSize; uint32 left = dataSize;
feed(); uint32 lenR = 0, lenW = 0;
unpack(); while (left > 0 && !_input->eos()) {
return _fed + _unpacked; lenR = _input->readByte();
}
void PackBitsReadStream::store(byte b) { if (lenR == 128) {
if (_out < _outEnd) { // no-op
*_out++ = b; lenW = 0;
_unpacked++; } else if (lenR <= 127) {
_wStoragePos = _storage; // literal run
} else { lenR++;
assert(_wStoragePos < _storage + 257); lenW = MIN(lenR, left);
*_wStoragePos++ = b; for (uint32 j = 0; j < lenW; j++) {
} *out++ = _input->readByte();
_rStoragePos = _storage;
}
void PackBitsReadStream::feed() {
_fed = 0;
int len = MIN(_wStoragePos - _rStoragePos, _outEnd - _out);
if (len == 0) return;
for (int i = 0; i < len; i++)
*_out++ = *_rStoragePos++;
_fed = len;
}
void PackBitsReadStream::unpack() {
byte byteRun;
byte idx;
uint32 i, j;
_unpacked = 0;
while (_out < _outEnd && !_input->eos()) {
byteRun = _input->readByte();
//FIXME: eos definition needs to be changed in parallaction engine
// which is the only place where this class is used
//if (_input->eos()) break;
if (byteRun <= 127) {
i = byteRun + 1;
for (j = 0; j < i; j++) {
idx = _input->readByte();
store(idx);
} }
} else if (byteRun != 128) { for ( ; lenR > lenW; lenR--) {
i = (256 - byteRun) + 1; _input->readByte();
idx = _input->readByte();
for (j = 0; j < i; j++) {
store(idx);
} }
} else { // len > 128
// expand run
lenW = MIN((256 - lenR) + 1, left);
byte val = _input->readByte();
memset(out, val, lenW);
out += lenW;
} }
left -= lenW;
} }
return dataSize - left;
} }

View file

@ -108,33 +108,22 @@ void decodePBM(Common::ReadStream &input, Surface &surface, byte *&colors);
by Apple. It is also used to encode ILBM and PBM by Apple. It is also used to encode ILBM and PBM
subtypes of IFF files, and some flavours of TIFF. subtypes of IFF files, and some flavours of TIFF.
The following implementation uses a static storage As there is no compression across row boundaries
and is buffered, that means you can't destroy the in the above formats, read() will extract a *new*
input stream before you are done with it. line on each call, discarding any alignment or
padding.
*/ */
class PackBitsReadStream : public Common::ReadStream { class PackBitsReadStream : public Common::ReadStream {
protected: protected:
Common::ReadStream *_input; Common::ReadStream *_input;
byte _storage[257];
byte *_wStoragePos;
byte *_rStoragePos;
byte* _out;
byte* _outEnd;
int32 _fed;
int32 _unpacked;
void store(byte b);
void feed();
void unpack();
public: public:
PackBitsReadStream(Common::ReadStream &input); PackBitsReadStream(Common::ReadStream &input);
~PackBitsReadStream(); ~PackBitsReadStream();
virtual bool eos() const; virtual bool eos() const;
uint32 read(void *dataPtr, uint32 dataSize); uint32 read(void *dataPtr, uint32 dataSize);
}; };