aboutsummaryrefslogtreecommitdiff
path: root/engines/zvision
diff options
context:
space:
mode:
authorrichiesams2013-07-17 15:37:46 -0500
committerrichiesams2013-08-04 13:32:27 -0500
commit47161ef30d8d7350a92fe28a031437abb338732c (patch)
tree04b6a31858799feb71ba016143d24b0c7d200311 /engines/zvision
parent125a061a9650297d81a76cc8e77033ca099191b0 (diff)
downloadscummvm-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
Diffstat (limited to 'engines/zvision')
-rw-r--r--engines/zvision/image.cpp6
-rw-r--r--engines/zvision/lzss_read_stream.cpp62
-rw-r--r--engines/zvision/lzss_read_stream.h13
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);
};
}