* 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;
case 1: {
uint32 scanWidth = _bitmapHeader.width >> 3;
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);
@ -237,79 +236,49 @@ void PBMDecoder::readBODY(Common::IFFChunk& chunk) {
PackBitsReadStream::PackBitsReadStream(Common::ReadStream &input) : _input(&input), _wStoragePos(_storage), _rStoragePos(_storage) {
PackBitsReadStream::PackBitsReadStream(Common::ReadStream &input) : _input(&input) {
}
PackBitsReadStream::~PackBitsReadStream() {
}
bool PackBitsReadStream::eos() const {
//FIXME: eos definition needs to be changed in parallaction engine
// which is the only place where this class is used
return _input->eos() && (_rStoragePos == _wStoragePos);
return _input->eos();
}
uint32 PackBitsReadStream::read(void *dataPtr, uint32 dataSize) {
_out = (byte*)dataPtr;
_outEnd = _out + dataSize;
byte *out = (byte*)dataPtr;
uint32 left = dataSize;
feed();
unpack();
return _fed + _unpacked;
}
uint32 lenR = 0, lenW = 0;
while (left > 0 && !_input->eos()) {
lenR = _input->readByte();
void PackBitsReadStream::store(byte b) {
if (_out < _outEnd) {
*_out++ = b;
_unpacked++;
_wStoragePos = _storage;
} else {
assert(_wStoragePos < _storage + 257);
*_wStoragePos++ = b;
}
_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);
if (lenR == 128) {
// no-op
lenW = 0;
} else if (lenR <= 127) {
// literal run
lenR++;
lenW = MIN(lenR, left);
for (uint32 j = 0; j < lenW; j++) {
*out++ = _input->readByte();
}
} else if (byteRun != 128) {
i = (256 - byteRun) + 1;
idx = _input->readByte();
for (j = 0; j < i; j++) {
store(idx);
for ( ; lenR > lenW; lenR--) {
_input->readByte();
}
} 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
subtypes of IFF files, and some flavours of TIFF.
The following implementation uses a static storage
and is buffered, that means you can't destroy the
input stream before you are done with it.
As there is no compression across row boundaries
in the above formats, read() will extract a *new*
line on each call, discarding any alignment or
padding.
*/
class PackBitsReadStream : public Common::ReadStream {
protected:
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:
PackBitsReadStream(Common::ReadStream &input);
~PackBitsReadStream();
virtual bool eos() const;
uint32 read(void *dataPtr, uint32 dataSize);
};