aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorPaul Gilbert2019-09-08 12:25:46 -0700
committerPaul Gilbert2019-09-25 20:13:27 -0700
commitc03b7a50eafe3c6a559c55746ec88d5a37885e9a (patch)
treebe028fbaead87b7d1445f9fe74dc1ad731239e3d /common
parent855b75f6dfd602879b7153e576124749d8c47c92 (diff)
downloadscummvm-rg350-c03b7a50eafe3c6a559c55746ec88d5a37885e9a.tar.gz
scummvm-rg350-c03b7a50eafe3c6a559c55746ec88d5a37885e9a.tar.bz2
scummvm-rg350-c03b7a50eafe3c6a559c55746ec88d5a37885e9a.zip
GLK: ADRIFT: Implement zlib decompression
Diffstat (limited to 'common')
-rw-r--r--common/zlib.cpp73
-rw-r--r--common/zlib.h12
2 files changed, 85 insertions, 0 deletions
diff --git a/common/zlib.cpp b/common/zlib.cpp
index 6afffb14d2..e4a3d47e35 100644
--- a/common/zlib.cpp
+++ b/common/zlib.cpp
@@ -141,6 +141,79 @@ bool inflateZlibInstallShield(byte *dst, uint dstLen, const byte *src, uint srcL
return true;
}
+bool inflateZlibHeaderless(Common::WriteStream *dst, Common::SeekableReadStream *src) {
+ byte *inBuffer, *outBuffer;
+ z_stream stream;
+ int status;
+
+ // Allocate buffers
+ inBuffer = new byte[kTempBufSize];
+ outBuffer = new byte[kTempBufSize];
+
+ /* Initialize Zlib inflation functions. */
+ stream.next_out = outBuffer;
+ stream.avail_out = kTempBufSize;
+ stream.next_in = inBuffer;
+ stream.avail_in = 0;
+
+ stream.zalloc = Z_NULL;
+ stream.zfree = Z_NULL;
+ stream.opaque = Z_NULL;
+
+ status = inflateInit(&stream);
+ if (status != Z_OK) {
+ delete[] inBuffer;
+ delete[] outBuffer;
+ return false;
+ }
+
+ // Inflate the input buffers. */
+ for (;;) {
+ int inBytes, outBytes;
+
+ /* If the input buffer is empty, try to obtain more data. */
+ if (stream.avail_in == 0) {
+ inBytes = src->read(inBuffer, kTempBufSize);
+ stream.next_in = inBuffer;
+ stream.avail_in = inBytes;
+ }
+
+ // Decompress as much stream data as we can. */
+ status = inflate(&stream, Z_SYNC_FLUSH);
+ if (status != Z_STREAM_END && status != Z_OK) {
+ delete[] inBuffer;
+ delete[] outBuffer;
+ return false;
+ }
+ outBytes = kTempBufSize - stream.avail_out;
+
+ // See if decompressed data is available. */
+ if (outBytes > 0) {
+ // Add data from the buffer to the output
+ int consumed = dst->write(outBuffer, outBytes);
+
+ // Move unused buffer data to buffer start
+ memmove(outBuffer, outBuffer + consumed, kTempBufSize - consumed);
+
+ // Reset inflation stream for available space
+ stream.next_out = outBuffer + outBytes - consumed;
+ stream.avail_out += consumed;
+ }
+
+ // If at inflation stream end and output is empty, leave loop
+ if (status == Z_STREAM_END && stream.avail_out == kTempBufSize)
+ break;
+ }
+
+ // End inflation buffers
+ status = inflateEnd(&stream);
+ delete[] inBuffer;
+ delete[] outBuffer;
+
+ // Return result
+ return (status == Z_OK);
+}
+
#ifndef RELEASE_BUILD
static bool _shownBackwardSeekingWarning = false;
#endif
diff --git a/common/zlib.h b/common/zlib.h
index eb0548344d..a172399511 100644
--- a/common/zlib.h
+++ b/common/zlib.h
@@ -96,6 +96,18 @@ bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen,
*/
bool inflateZlibInstallShield(byte *dst, uint dstLen, const byte *src, uint srcLen);
+/**
+ * Wrapper around zlib's inflate functions. This function is used by Glk to
+ * decompress TAF 4.0 files, which are headerless Zlib compressed streams with a
+ * custom header
+ *
+ * @param dst the destination stream to write decompressed data out to
+ * @param src the Source stream
+ *
+ * @return true on success (Z_OK or Z_STREAM_END), false otherwise.
+ */
+bool inflateZlibHeaderless(Common::WriteStream *dst, Common::SeekableReadStream *src);
+
#endif
/**