* 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:
parent
a6497584cc
commit
cbf9996abb
2 changed files with 34 additions and 76 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue