aboutsummaryrefslogtreecommitdiff
path: root/common/iff_container.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/iff_container.cpp')
-rw-r--r--common/iff_container.cpp49
1 files changed, 48 insertions, 1 deletions
diff --git a/common/iff_container.cpp b/common/iff_container.cpp
index 7bcbf86e0f..9c6e5f124a 100644
--- a/common/iff_container.cpp
+++ b/common/iff_container.cpp
@@ -22,6 +22,7 @@
#include "common/iff_container.h"
#include "common/substream.h"
+#include "common/util.h"
namespace Common {
@@ -75,4 +76,50 @@ void IFFParser::parse(IFFCallback &callback) {
} while (!stop);
}
-} // End of namespace Common
+
+PackBitsReadStream::PackBitsReadStream(Common::ReadStream &input) : _input(&input) {
+}
+
+PackBitsReadStream::~PackBitsReadStream() {
+}
+
+bool PackBitsReadStream::eos() const {
+ return _input->eos();
+}
+
+uint32 PackBitsReadStream::read(void *dataPtr, uint32 dataSize) {
+ byte *out = (byte *)dataPtr;
+ uint32 left = dataSize;
+
+ uint32 lenR = 0, lenW = 0;
+ while (left > 0 && !_input->eos()) {
+ lenR = _input->readByte();
+
+ 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();
+ }
+ 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;
+}
+
+} // End of namespace Common