diff options
author | richiesams | 2013-07-17 15:37:46 -0500 |
---|---|---|
committer | richiesams | 2013-08-04 13:32:27 -0500 |
commit | 47161ef30d8d7350a92fe28a031437abb338732c (patch) | |
tree | 04b6a31858799feb71ba016143d24b0c7d200311 | |
parent | 125a061a9650297d81a76cc8e77033ca099191b0 (diff) | |
download | scummvm-rg350-47161ef30d8d7350a92fe28a031437abb338732c.tar.gz scummvm-rg350-47161ef30d8d7350a92fe28a031437abb338732c.tar.bz2 scummvm-rg350-47161ef30d8d7350a92fe28a031437abb338732c.zip |
ZVISION: LZSSReadStream - Decompress directly to the destination buffer instead of an intermediate buffer
-rw-r--r-- | engines/zvision/image.cpp | 6 | ||||
-rw-r--r-- | engines/zvision/lzss_read_stream.cpp | 62 | ||||
-rw-r--r-- | engines/zvision/lzss_read_stream.h | 13 |
3 files changed, 20 insertions, 61 deletions
diff --git a/engines/zvision/image.cpp b/engines/zvision/image.cpp index 6e6b802739..cacfec302c 100644 --- a/engines/zvision/image.cpp +++ b/engines/zvision/image.cpp @@ -52,9 +52,9 @@ void ZVision::renderImageToScreen(const Common::String &fileName, uint32 x, uint uint32 width = file.readSint32LE(); uint32 height = file.readSint32LE(); - LzssReadStream stream(&file, false, decompressedSize); - byte *buffer = new byte[stream.currentSize()]; - stream.read(buffer, stream.currentSize()); + LzssReadStream stream(&file); + byte *buffer = new byte[decompressedSize]; + stream.read(buffer, decompressedSize); _system->copyRectToScreen(buffer, width * 2, x, y, width, height); } else { diff --git a/engines/zvision/lzss_read_stream.cpp b/engines/zvision/lzss_read_stream.cpp index 2d7acdb8ce..35c708a6c7 100644 --- a/engines/zvision/lzss_read_stream.cpp +++ b/engines/zvision/lzss_read_stream.cpp @@ -26,7 +26,7 @@ namespace ZVision { -LzssReadStream::LzssReadStream(Common::SeekableReadStream *source, bool stream, uint32 decompressedSize) +LzssReadStream::LzssReadStream(Common::SeekableReadStream *source) : _source(source), // It's convention to set the starting cursor position to blockSize - 16 _windowCursor(0x0FEE), @@ -34,24 +34,12 @@ LzssReadStream::LzssReadStream(Common::SeekableReadStream *source, bool stream, _eosFlag(false) { // Clear the window to null memset(_window, 0, _blockSize); - - // Reserve space in the destination buffer - // TODO: Make a better guess - if (decompressedSize == _npos) { - decompressedSize = source->size(); - } - _destination.reserve(decompressedSize); - - if (stream) - decompressBytes(_blockSize); - else - decompressAll(); } -void LzssReadStream::decompressBytes(uint32 numberOfBytes) { - uint32 bytesRead = 0; +uint32 LzssReadStream::decompressBytes(byte *destination, uint32 numberOfBytes) { + uint32 destinationCursor = 0; - while (!_source->eos() && bytesRead <= numberOfBytes) { + while (destinationCursor < numberOfBytes) { byte flagbyte = _source->readByte(); if (_source->eos()) break; @@ -61,12 +49,11 @@ void LzssReadStream::decompressBytes(uint32 numberOfBytes) { if ((flagbyte & mask) == mask) { byte data = _source->readByte(); - bytesRead++; if (_source->eos()) - break; + return destinationCursor; _window[_windowCursor] = data; - _destination.push_back(data); + destination[destinationCursor++] = data; // Increment and wrap the window cursor _windowCursor = (_windowCursor + 1) & 0xFFF; @@ -74,14 +61,12 @@ void LzssReadStream::decompressBytes(uint32 numberOfBytes) { else { byte low = _source->readByte(); - bytesRead++; if (_source->eos()) - break; + return destinationCursor; byte high = _source->readByte(); - bytesRead++; if (_source->eos()) - break; + return destinationCursor; uint16 length = (high & 0xF) + 2; uint16 offset = low | ((high & 0xF0)<<4); @@ -90,7 +75,7 @@ void LzssReadStream::decompressBytes(uint32 numberOfBytes) { { byte temp = _window[(offset + j) & 0xFFF]; _window[_windowCursor] = temp; - _destination.push_back(temp); + destination[destinationCursor++] = temp; _windowCursor = (_windowCursor + 1) & 0xFFF; } }; @@ -98,10 +83,8 @@ void LzssReadStream::decompressBytes(uint32 numberOfBytes) { mask = mask << 1; } } -} -void LzssReadStream::decompressAll() { - decompressBytes(_source->size()); + return destinationCursor; } bool LzssReadStream::eos() const { @@ -109,30 +92,13 @@ bool LzssReadStream::eos() const { } uint32 LzssReadStream::read(void *dataPtr, uint32 dataSize) { - // Check if there are enough bytes available - // If not, keep decompressing until we have enough bytes or until we reach EOS - while (dataSize > _destination.size() - _readCursor) { - // Check if we can read any more data from source - if (_source->eos()) { - // Shorten the dataSize to what we have left and flag that we're at EOS - dataSize = _destination.size() - _readCursor; - _eosFlag = true; - break; - } - - decompressBytes(_blockSize); - } - - if (dataSize > 0) { - memcpy(dataPtr, _destination.begin() + _readCursor, dataSize); - _readCursor += dataSize; + uint32 bytesRead = decompressBytes(static_cast<byte *>(dataPtr), dataSize); + if (bytesRead < dataSize) { + // Flag that we're at EOS + _eosFlag = true; } return dataSize; } -uint32 LzssReadStream::currentSize() const { - return _destination.size(); -} - } // End of namespace ZVision diff --git a/engines/zvision/lzss_read_stream.h b/engines/zvision/lzss_read_stream.h index 142bf9e1a2..0dea25b325 100644 --- a/engines/zvision/lzss_read_stream.h +++ b/engines/zvision/lzss_read_stream.h @@ -34,14 +34,11 @@ class LzssReadStream : public Common::ReadStream { public: /** * A class that decompresses LZSS data and implements ReadStream for easy access - * to the decompiled data. It can either decompress all the data in the beginning - * or decompress as needed by read(). + * to the decompiled data. * * @param source The source data - * @param stream Decompress the data as needed (true) or all at once (false) - * @param decompressedSize The size of the decompressed data. If npos, the class will choose a size and grow as needed */ - LzssReadStream(Common::SeekableReadStream *source, bool stream = true, uint32 decompressedSize = _npos); + LzssReadStream(Common::SeekableReadStream *source); public: static const uint32 _npos = 0xFFFFFFFFu; @@ -49,7 +46,6 @@ public: private: Common::SeekableReadStream *_source; - Common::Array<char> _destination; char _window[_blockSize]; uint16 _windowCursor; uint32 _readCursor; @@ -58,7 +54,6 @@ private: public: bool eos() const; uint32 read(void *dataPtr, uint32 dataSize); - uint32 currentSize() const; private: /** @@ -66,9 +61,7 @@ private: * * @param numberOfBytes How many bytes to decompress. This is a count of source bytes, not destination bytes */ - void decompressBytes(uint32 numberOfBytes); - /** Decompress all of the source stream. */ - void decompressAll(); + uint32 decompressBytes(byte* destination, uint32 numberOfBytes); }; } |