[Scummvm-git-logs] scummvm master -> 2f7c2149e5b3e8e0e7912a387ea80413e8b1341d

sev- noreply at scummvm.org
Mon Aug 28 19:49:11 UTC 2023


This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
ead4171bbd COMMON: Rewrite writeStream to work with any ReadStream
b5e3173b10 COMMON: Fix inflateZlibHeaderless name
5edf74d8a6 COMMON: Cleanup flags defines
191bde03ad COMMON: Use memcpy instead of memmove
be3eb09753 COMMON: Allow GZipReadStream to work on data in the middle of stream
5bdd9e6f50 ALL: Unify zlib and gzio API
7c9df6c2bf GLK: ADRIFT: Use wrapCompressedReadStream instead of specific function
2f7c2149e5 COMMON: Remove useless inflateZlib function


Commit: ead4171bbd9e5e4626c47fa0763e6e8810efc96f
    https://github.com/scummvm/scummvm/commit/ead4171bbd9e5e4626c47fa0763e6e8810efc96f
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-08-28T21:49:03+02:00

Commit Message:
COMMON: Rewrite writeStream to work with any ReadStream

This let it work with stream without a known size and avoids allocating
big buffers when file is big.

Changed paths:
    common/stream.cpp
    common/stream.h


diff --git a/common/stream.cpp b/common/stream.cpp
index 9eaf4333eb4..a444d832890 100644
--- a/common/stream.cpp
+++ b/common/stream.cpp
@@ -27,6 +27,10 @@
 
 namespace Common {
 
+enum {
+	kTempBufSize = 65536
+};
+
 uint32 WriteStream::writeStream(ReadStream *stream, uint32 dataSize) {
 	void *buf = malloc(dataSize);
 	dataSize = stream->read(buf, dataSize);
@@ -36,8 +40,21 @@ uint32 WriteStream::writeStream(ReadStream *stream, uint32 dataSize) {
 	return dataSize;
 }
 
-uint32 WriteStream::writeStream(SeekableReadStream *stream) {
-	return writeStream(stream, stream->size());
+uint32 WriteStream::writeStream(ReadStream *stream) {
+	uint32 ret = 0;
+
+	void *buf = malloc(kTempBufSize);
+	assert(buf);
+
+	uint32 readSize, writeSize;
+	do {
+		readSize = stream->read(buf, kTempBufSize);
+		writeSize = write(buf, readSize);
+		ret += writeSize;
+	} while(readSize == kTempBufSize && writeSize == readSize);
+
+	free(buf);
+	return ret;
 }
 
 void WriteStream::writeString(const String &str) {
diff --git a/common/stream.h b/common/stream.h
index 07ab3777f51..e290b76f3bc 100644
--- a/common/stream.h
+++ b/common/stream.h
@@ -288,7 +288,7 @@ public:
 	 *
 	 * @return The number of bytes written into the stream.
 	 */
-	uint32 writeStream(SeekableReadStream *stream);
+	uint32 writeStream(ReadStream *stream);
 
 	/**
 	 * Write the given string to the stream.


Commit: b5e3173b10241fcc0a566f094855841b559c12f8
    https://github.com/scummvm/scummvm/commit/b5e3173b10241fcc0a566f094855841b559c12f8
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-08-28T21:49:03+02:00

Commit Message:
COMMON: Fix inflateZlibHeaderless name

The function takes a stream beginning with zlib header unlike the name
suggests.
inflateInit expects to parse a zlib header.

Changed paths:
    common/compression/zlib.cpp
    common/compression/zlib.h
    engines/glk/adrift/sctaffil.cpp


diff --git a/common/compression/zlib.cpp b/common/compression/zlib.cpp
index b280ec12cd8..17c6a058215 100644
--- a/common/compression/zlib.cpp
+++ b/common/compression/zlib.cpp
@@ -142,7 +142,7 @@ bool inflateZlibInstallShield(byte *dst, uint dstLen, const byte *src, uint srcL
 	return true;
 }
 
-bool inflateZlibHeaderless(Common::WriteStream *dst, Common::SeekableReadStream *src) {
+bool inflateZlib(Common::WriteStream *dst, Common::SeekableReadStream *src) {
 	byte *inBuffer, *outBuffer;
 	z_stream stream;
 	int status;
diff --git a/common/compression/zlib.h b/common/compression/zlib.h
index 56752fb5589..aaaca3c4041 100644
--- a/common/compression/zlib.h
+++ b/common/compression/zlib.h
@@ -106,15 +106,15 @@ bool inflateZlibInstallShield(byte *dst, uint dstLen, const byte *src, uint srcL
 
 /**
  * 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
+ * decompress TAF 4.0 files, which are 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);
+bool inflateZlib(Common::WriteStream *dst, Common::SeekableReadStream *src);
 
 #endif
 
diff --git a/engines/glk/adrift/sctaffil.cpp b/engines/glk/adrift/sctaffil.cpp
index f21f50c4cba..68dbabf4215 100644
--- a/engines/glk/adrift/sctaffil.cpp
+++ b/engines/glk/adrift/sctaffil.cpp
@@ -396,7 +396,7 @@ static sc_bool taf_decompress(sc_tafref_t taf, sc_read_callbackref_t callback,
 	Common::MemoryWriteStreamDynamic dest(DisposeAfterUse::YES);
 	size_t startingPos = src->pos();
 
-	if (!Common::inflateZlibHeaderless(&dest, src))
+	if (!Common::inflateZlib(&dest, src))
 		return false;
 
 	// Iterate through pushing data out to the taf file


Commit: 5edf74d8a6c416ce3641b6e6dbd487f436e1b07d
    https://github.com/scummvm/scummvm/commit/5edf74d8a6c416ce3641b6e6dbd487f436e1b07d
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-08-28T21:49:03+02:00

Commit Message:
COMMON: Cleanup flags defines

In addition, use flags from RFC and not from (really) old gzip
implementations.

Changed paths:
    common/compression/gzio.cpp


diff --git a/common/compression/gzio.cpp b/common/compression/gzio.cpp
index d9d85c9fcbe..a97bec00e8b 100644
--- a/common/compression/gzio.cpp
+++ b/common/compression/gzio.cpp
@@ -43,24 +43,15 @@
 
 
 /* Compression methods (see algorithm.doc) */
-#define GRUB_GZ_STORED      0
-#define GRUB_GZ_COMPRESSED  1
-#define GRUB_GZ_PACKED      2
-#define GRUB_GZ_LZHED       3
-/* methods 4 to 7 reserved */
-#define GRUB_GZ_DEFLATED    8
-#define GRUB_GZ_MAX_METHODS 9
+#define GZ_DEFLATED    8
 
 /* gzip flag byte */
-#define GRUB_GZ_ASCII_FLAG   0x01	/* bit 0 set: file probably ascii text */
-#define GRUB_GZ_CONTINUATION 0x02	/* bit 1 set: continuation of multi-part gzip file */
-#define GRUB_GZ_EXTRA_FIELD  0x04	/* bit 2 set: extra field present */
-#define GRUB_GZ_ORIG_NAME    0x08	/* bit 3 set: original file name present */
-#define GRUB_GZ_COMMENT      0x10	/* bit 4 set: file comment present */
-#define GRUB_GZ_ENCRYPTED    0x20	/* bit 5 set: file is encrypted */
-#define GRUB_GZ_RESERVED     0xC0	/* bit 6,7:   reserved */
-
-#define GRUB_GZ_UNSUPPORTED_FLAGS	(GRUB_GZ_CONTINUATION | GRUB_GZ_ENCRYPTED | GRUB_GZ_RESERVED)
+#define GZ_ASCII_FLAG   0x01	/* bit 0 set: file probably ascii text */
+#define GZ_CRC          0x02	/* bit 1 set: crc present */
+#define GZ_EXTRA_FIELD  0x04	/* bit 2 set: extra field present */
+#define GZ_ORIG_NAME    0x08	/* bit 3 set: original file name present */
+#define GZ_COMMENT      0x10	/* bit 4 set: file comment present */
+#define GZ_RESERVED     0xE0	/* bit 5,6,7:   reserved */
 
 /* inflate block codes */
 #define INFLATE_STORED	0
@@ -1033,7 +1024,7 @@ GzioReadStream::test_zlib_header ()
   flg = parentGetByte ();
 
   /* Check that compression method is DEFLATE.  */
-  if ((cmf & 0xf) != GRUB_GZ_DEFLATED)
+  if ((cmf & 0xf) != GZ_DEFLATED)
     {
       return false;
     }


Commit: 191bde03ad1e25c2299a17aca7f8a63d60111487
    https://github.com/scummvm/scummvm/commit/191bde03ad1e25c2299a17aca7f8a63d60111487
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-08-28T21:49:03+02:00

Commit Message:
COMMON: Use memcpy instead of memmove

memove was used although the buffers were not overlapping.
Using memcpy allows for better optimizations by compiler.

Changed paths:
    common/compression/gzio.cpp


diff --git a/common/compression/gzio.cpp b/common/compression/gzio.cpp
index a97bec00e8b..d29badb14c7 100644
--- a/common/compression/gzio.cpp
+++ b/common/compression/gzio.cpp
@@ -580,7 +580,7 @@ GzioReadStream::inflate_codes_in_window()
 
 	      if (w - d >= e)
 		{
-		  memmove (_slide + w, _slide + d, e);
+		  memcpy (_slide + w, _slide + d, e);
 		  w += e;
 		  d += e;
 		}
@@ -1083,7 +1083,7 @@ GzioReadStream::readAtOffset (int64 offset, byte *buf, uint32 len)
       if (size > len)
 	size = len;
 
-      memmove (buf, srcaddr, size);
+      memcpy (buf, srcaddr, size);
 
       buf += size;
       len -= size;


Commit: be3eb097536e5d1b67456cbbdb15ba9518ef8470
    https://github.com/scummvm/scummvm/commit/be3eb097536e5d1b67456cbbdb15ba9518ef8470
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-08-28T21:49:03+02:00

Commit Message:
COMMON: Allow GZipReadStream to work on data in the middle of stream

Changed paths:
    common/compression/zlib.cpp


diff --git a/common/compression/zlib.cpp b/common/compression/zlib.cpp
index 17c6a058215..0d3d06cc6a4 100644
--- a/common/compression/zlib.cpp
+++ b/common/compression/zlib.cpp
@@ -235,6 +235,7 @@ protected:
 	ScopedPtr<SeekableReadStream> _wrapped;
 	z_stream _stream;
 	int _zlibErr;
+	uint64 _parentPos;
 	uint32 _pos;
 	uint32 _origSize;
 	bool _eos;
@@ -244,8 +245,8 @@ public:
 	GZipReadStream(SeekableReadStream *w, uint32 knownSize = 0) : _wrapped(w), _stream() {
 		assert(w != nullptr);
 
+		_parentPos = w->pos();
 		// Verify file header is correct
-		w->seek(0, SEEK_SET);
 		uint16 header = w->readUint16BE();
 		assert(header == 0x1F8B ||
 		       ((header & 0x0F00) == 0x0800 && header % 31 == 0));
@@ -259,8 +260,8 @@ public:
 			// use an otherwise known size if supplied.
 			_origSize = knownSize;
 		}
+		w->seek(_parentPos, SEEK_SET);
 		_pos = 0;
-		w->seek(0, SEEK_SET);
 		_eos = false;
 
 		// Adding 32 to windowBits indicates to zlib that it is supposed to
@@ -354,7 +355,7 @@ public:
 #endif
 
 			_pos = 0;
-			_wrapped->seek(0, SEEK_SET);
+			_wrapped->seek(_parentPos, SEEK_SET);
 			_zlibErr = inflateReset(&_stream);
 			if (_zlibErr != Z_OK)
 				return false; // FIXME: STREAM REWRITE


Commit: 5bdd9e6f50111b4145989b1f97c22cdff5a2d8cb
    https://github.com/scummvm/scummvm/commit/5bdd9e6f50111b4145989b1f97c22cdff5a2d8cb
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-08-28T21:49:03+02:00

Commit Message:
ALL: Unify zlib and gzio API

zlib is used when available and falls back on gzio.
This allows performance improvements as our CRC32 and gzio
implementations are slower than base zlib.
As zlib is available when libpng is present, this is sensible to
benefit from it.

Changed paths:
  A common/compression/deflate.h
  R common/compression/gzio.h
  R common/compression/zlib.h
    backends/platform/dc/vmsave.cpp
    backends/platform/n64/framfs_save_manager.h
    backends/platform/n64/pakfs_save_manager.h
    backends/saves/default/default-saves.cpp
    common/compression/clickteam.cpp
    common/compression/gzio.cpp
    common/compression/installshield_cab.cpp
    common/compression/module.mk
    common/compression/unzip.cpp
    common/compression/vise.cpp
    common/compression/zlib.cpp
    common/formats/quicktime.cpp
    engines/agos/res.cpp
    engines/composer/saveload.cpp
    engines/director/tests.cpp
    engines/director/util.cpp
    engines/dreamweb/rnca_archive.cpp
    engines/glk/adrift/sctaffil.cpp
    engines/grim/configure.engine
    engines/grim/patchr.cpp
    engines/grim/resource.cpp
    engines/grim/update/mscab.cpp
    engines/hadesch/hadesch.cpp
    engines/hdb/configure.engine
    engines/hdb/file-manager.cpp
    engines/icb/configure.engine
    engines/mtropolis/boot.cpp
    engines/scumm/saveload.cpp
    engines/scumm/smush/smush_player.cpp
    engines/scumm/smush/smush_player.h
    engines/sword25/configure.engine
    engines/sword25/kernel/persistenceservice.cpp
    engines/teenagent/resources.cpp
    engines/tetraedge/te/te_free_move_zone.cpp
    engines/tetraedge/te/te_model.cpp
    engines/tetraedge/te/te_model_animation.cpp
    engines/tetraedge/te/te_zlib_jpeg.cpp
    engines/titanic/configure.engine
    engines/titanic/support/files_manager.cpp
    engines/titanic/support/simple_file.h
    engines/wintermute/base/file/base_disk_file.cpp
    engines/wintermute/base/file/base_file_entry.cpp
    engines/wintermute/base/gfx/xfile_loader.cpp
    engines/wintermute/base/gfx/xmodel.cpp
    engines/wintermute/configure.engine
    video/dxa_decoder.cpp


diff --git a/backends/platform/dc/vmsave.cpp b/backends/platform/dc/vmsave.cpp
index 89183b0852b..523b722ae34 100644
--- a/backends/platform/dc/vmsave.cpp
+++ b/backends/platform/dc/vmsave.cpp
@@ -28,7 +28,7 @@
 #include <common/savefile.h>
 #include <gui/gui-manager.h>
 #include <gui/message.h>
-#include <common/compression/zlib.h>
+#include <common/compression/deflate.h>
 
 
 // Savegame can not be bigger than this
diff --git a/backends/platform/n64/framfs_save_manager.h b/backends/platform/n64/framfs_save_manager.h
index 2d50d7d5fed..02a54a7875a 100644
--- a/backends/platform/n64/framfs_save_manager.h
+++ b/backends/platform/n64/framfs_save_manager.h
@@ -23,7 +23,7 @@
 #define __FRAMFS_SAVE_MANAGER__
 
 #include <common/savefile.h>
-#include <common/compression/zlib.h>
+#include <common/compression/deflate.h>
 
 #include <framfs.h> // N64 FramFS library
 
diff --git a/backends/platform/n64/pakfs_save_manager.h b/backends/platform/n64/pakfs_save_manager.h
index d3ca3600cd9..90d8303ba99 100644
--- a/backends/platform/n64/pakfs_save_manager.h
+++ b/backends/platform/n64/pakfs_save_manager.h
@@ -23,7 +23,7 @@
 #define __PAKFS_SAVE_MANAGER__
 
 #include <common/savefile.h>
-#include <common/compression/zlib.h>
+#include <common/compression/deflate.h>
 
 #include <pakfs.h> // N64 PakFS library
 
diff --git a/backends/saves/default/default-saves.cpp b/backends/saves/default/default-saves.cpp
index 4b15fe230d6..1306b3ddc18 100644
--- a/backends/saves/default/default-saves.cpp
+++ b/backends/saves/default/default-saves.cpp
@@ -36,7 +36,7 @@
 #include "common/fs.h"
 #include "common/archive.h"
 #include "common/config-manager.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 #include <errno.h>	// for removeSavefile()
 
diff --git a/common/compression/clickteam.cpp b/common/compression/clickteam.cpp
index da96087a3f9..8a525ebd430 100644
--- a/common/compression/clickteam.cpp
+++ b/common/compression/clickteam.cpp
@@ -21,7 +21,7 @@
 
 #include "common/array.h"
 #include "common/compression/clickteam.h"
-#include "common/compression/gzio.h"
+#include "common/compression/deflate.h"
 #include "common/debug.h"
 #include "common/ptr.h"
 #include "common/substream.h"
@@ -384,12 +384,12 @@ ClickteamInstaller* ClickteamInstaller::openPatch(Common::SeekableReadStream *st
 			}
 			uint32 uncompressedPayloadLen = READ_LE_UINT32(compressedPayload);
 			byte *uncompressedPayload = new byte[uncompressedPayloadLen];
-			int32 ret = Common::GzioReadStream::clickteamDecompress(uncompressedPayload,
-										uncompressedPayloadLen,
-										compressedPayload + 4,
-										compressedPayloadLen - 4);
+			bool ret = inflateClickteam(uncompressedPayload,
+			                             uncompressedPayloadLen,
+			                             compressedPayload + 4,
+			                             compressedPayloadLen - 4);
 			delete[] compressedPayload;
-			if (ret < 0) {
+			if (!ret) {
 				warning("Decompression error for tag 0x%04x", tagId);
 				continue;
 			}
@@ -547,7 +547,7 @@ Common::SharedArchiveContents ClickteamInstaller::readContentsForPath(const Comm
 				return Common::SharedArchiveContents();
 			}
 
-			uncompressedPatchStream.reset(GzioReadStream::openClickteam(compressedPatchStream, patchUncompressedSize, DisposeAfterUse::YES));
+			uncompressedPatchStream.reset(wrapClickteamReadStream(compressedPatchStream, DisposeAfterUse::YES, patchUncompressedSize));
 		} else {
 			uncompressedPatchStream.reset(new Common::SafeSeekableSubReadStream(
 							      _stream.get(), patchStart, patchStart + patchCompressedSize));
@@ -566,7 +566,7 @@ Common::SharedArchiveContents ClickteamInstaller::readContentsForPath(const Comm
 				return Common::SharedArchiveContents();
 			}
 
-			uncompressedLiteralsStream.reset(GzioReadStream::openClickteam(compressedLiteralsStream, literalsUncompressedSize, DisposeAfterUse::YES));
+			uncompressedLiteralsStream.reset(wrapClickteamReadStream(compressedLiteralsStream, DisposeAfterUse::YES, literalsUncompressedSize));
 		} else {
 			uncompressedLiteralsStream.reset(new Common::SafeSeekableSubReadStream(
 								 _stream.get(), literalsStart, literalsStart + literalsCompressedSize));
@@ -587,7 +587,7 @@ Common::SharedArchiveContents ClickteamInstaller::readContentsForPath(const Comm
 			return Common::SharedArchiveContents();
 		}
 
-		Common::ScopedPtr<Common::SeekableReadStream> uncStream(GzioReadStream::openClickteam(subStream, desc._uncompressedSize, DisposeAfterUse::YES));
+		Common::ScopedPtr<Common::SeekableReadStream> uncStream(wrapClickteamReadStream(subStream, DisposeAfterUse::YES, desc._uncompressedSize));
 		if (!uncStream) {
 			warning("Decompression error");
 			return Common::SharedArchiveContents();
diff --git a/common/compression/zlib.h b/common/compression/deflate.h
similarity index 67%
rename from common/compression/zlib.h
rename to common/compression/deflate.h
index aaaca3c4041..5e655c19314 100644
--- a/common/compression/zlib.h
+++ b/common/compression/deflate.h
@@ -23,14 +23,15 @@
 #define COMMON_ZLIB_H
 
 #include "common/scummsys.h"
+#include "common/types.h"
 
 namespace Common {
 
 /**
- * @defgroup common_zlib zlib
+ * @defgroup common_deflate deflate
  * @ingroup common
  *
- * @brief API for zlib operations.
+ * @brief API for deflate based operations.
  *
  * @{
  */
@@ -38,8 +39,6 @@ namespace Common {
 class SeekableReadStream;
 class WriteStream;
 
-#if defined(USE_ZLIB)
-
 /**
  * Thin wrapper around zlib's uncompress() function. This wrapper makes
  * it possible to uncompress data in engines without being forced to link
@@ -59,7 +58,10 @@ class WriteStream;
  *
  * @return true on success (i.e. Z_OK), false otherwise.
  */
-bool uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long srcLen);
+bool inflateZlib(byte *dst, unsigned long *dstLen, const byte *src, unsigned long srcLen);
+static inline bool inflateZlib(byte *dst, unsigned long  dstLen, const byte *src, unsigned long srcLen) {
+	return inflateZlib(dst, &dstLen, src, srcLen);
+}
 
 /**
  * Wrapper around zlib's inflate functions. This function will call the
@@ -83,12 +85,15 @@ bool uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long
  *
  * @return true on success (Z_OK or Z_STREAM_END), false otherwise.
  */
-bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen, const byte *dict = nullptr, uint dictLen = 0);
+bool inflateZlibHeaderless(byte *dst, uint *dstLen, const byte *src, uint srcLen, const byte *dict = nullptr, uint dictLen = 0);
+static inline bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen, const byte *dict = nullptr, uint dictLen = 0) {
+	return inflateZlibHeaderless(dst, &dstLen, src, srcLen, dict, dictLen);
+}
 
 /**
  * Wrapper around zlib's inflate functions. This function will call the
- * necessary inflate functions to uncompress data compressed for InstallShield
- * cabinet files.
+ * modified inflate functions to uncompress data compressed for Clickteam
+ * Installer files.
  *
  * Decompresses the src buffer into the dst buffer.
  * srcLen is the byte length of the source buffer, dstLen is the byte
@@ -102,7 +107,10 @@ bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen,
  *
  * @return true on success (Z_OK or Z_STREAM_END), false otherwise.
  */
-bool inflateZlibInstallShield(byte *dst, uint dstLen, const byte *src, uint srcLen);
+bool inflateClickteam(byte *dst, uint *dstLen, const byte *src, uint srcLen);
+static inline bool inflateClickteam(byte *dst, uint  dstLen, const byte *src, uint srcLen) {
+	return inflateClickteam(dst, &dstLen, src, srcLen);
+}
 
 /**
  * Wrapper around zlib's inflate functions. This function is used by Glk to
@@ -116,8 +124,6 @@ bool inflateZlibInstallShield(byte *dst, uint dstLen, const byte *src, uint srcL
  */
 bool inflateZlib(Common::WriteStream *dst, Common::SeekableReadStream *src);
 
-#endif
-
 /**
  * Take an arbitrary SeekableReadStream and wrap it in a custom stream which
  * provides transparent on-the-fly decompression. Assumes the data it
@@ -137,9 +143,42 @@ bool inflateZlib(Common::WriteStream *dst, Common::SeekableReadStream *src);
  * returned).
  *
  * @param toBeWrapped	the stream to be wrapped (if it is in gzip-format)
- * @param knownSize		a supplied length of the compressed data (if not available directly)
+ * @param knownSize	a supplied length of the uncompressed data (if not available directly)
+ */
+SeekableReadStream *wrapCompressedReadStream(SeekableReadStream *toBeWrapped,
+		DisposeAfterUse::Flag disposeParent = DisposeAfterUse::YES, uint64 knownSize = 0);
+
+/**
+ * Take an arbitrary SeekableReadStream and wrap it in a custom stream which
+ * provides transparent on-the-fly decompression. Assumes the data it
+ * retrieves from the wrapped stream is compressed with deflate algorithm.
+ *
+ * It is safe to call this with a NULL parameter (in this case, NULL is
+ * returned).
+ *
+ * @param toBeWrapped	the stream to be wrapped (if it is in gzip-format)
+ * @param knownSize	a supplied length of the uncompressed data (if not available directly)
+ */
+SeekableReadStream *wrapDeflateReadStream(SeekableReadStream *toBeWrapped,
+		DisposeAfterUse::Flag disposeParent = DisposeAfterUse::YES, uint64 knownSize = 0,
+		const byte *dict = nullptr, uint dictLen = 0);
+
+/**
+ * Take an arbitrary SeekableReadStream and wrap it in a custom stream which
+ * provides transparent on-the-fly decompression. Assumes the data it
+ * retrieves from the wrapped stream is compressed with the Clickteam deflate
+ * variant algorithm.
+ * The stream is returned wrapped, unless there is no ZLIB support,
+ * then NULL is returned and the old stream is destroyed.
+ *
+ * It is safe to call this with a NULL parameter (in this case, NULL is
+ * returned).
+ *
+ * @param toBeWrapped	the stream to be wrapped (if it is in gzip-format)
+ * @param knownSize	a supplied length of the compressed data (if not available directly)
  */
-SeekableReadStream *wrapCompressedReadStream(SeekableReadStream *toBeWrapped, uint32 knownSize = 0);
+SeekableReadStream *wrapClickteamReadStream(SeekableReadStream *toBeWrapped,
+		DisposeAfterUse::Flag disposeParent = DisposeAfterUse::YES, uint64 knownSize = 0);
 
 /**
  * Take an arbitrary WriteStream and wrap it in a custom stream which provides
diff --git a/common/compression/gzio.cpp b/common/compression/gzio.cpp
index d29badb14c7..f7e849bf6f5 100644
--- a/common/compression/gzio.cpp
+++ b/common/compression/gzio.cpp
@@ -39,7 +39,7 @@
 #include "common/stream.h"
 #include "common/ptr.h"
 #include "common/memstream.h"
-#include "common/compression/gzio.h"
+#include "common/compression/deflate.h"
 
 
 /* Compression methods (see algorithm.doc) */
@@ -211,6 +211,107 @@ static ush mask_bits[] =
 #define NEEDBITS(n) do {while(k<(n)){b|=((ulg)parentGetByte())<<k;k+=8;}} while (0)
 #define DUMPBITS(n) do {b>>=(n);k-=(n);} while (0)
 
+/* The state stored in filesystem-specific data.  */
+class GzioReadStream : public Common::SeekableReadStream
+{
+public:
+	enum class Mode { ZLIB, CLICKTEAM } _mode;
+
+	GzioReadStream(Common::SeekableReadStream *parent, DisposeAfterUse::Flag disposeParent, uint64 uncompressedSize, Mode mode, const byte *dict = nullptr, uint32 dict_size = 0) :
+		_dataOffset(parent->pos()), _blockType(0), _blockLen(0),
+		_lastBlock(0), _codeState (0), _inflateN(0),
+		_inflateD(0), _bb(0), _bk(0), _wp(0), _tl(nullptr),
+		_td(nullptr), _bl(0),
+		_bd(0), _savedOffset(0), _err(false), _mode(mode), _input(parent, disposeParent),
+		_inbufD(0), _inbufSize(0), _uncompressedSize(uncompressedSize), _streamPos(0), _eos(false) {
+
+		if (dict && dict_size) {
+			dict_size = MIN<uint32>(dict_size, sizeof(_slide));
+			memcpy(_slide + sizeof(_slide) - dict_size, dict, dict_size);
+		}
+	}
+
+	uint32 read(void *dataPtr, uint32 dataSize) override;
+
+	bool eos() const override { return _eos; }
+	bool err() const override { return _err; }
+	void clearErr() override { _eos = false; _err = false; }
+
+	int64 pos() const override { return _streamPos; }
+	int64 size() const override { return _uncompressedSize; }
+
+	bool seek(int64 offs, int whence = SEEK_SET) override;
+
+	void initialize_tables();
+	bool test_zlib_header();
+	bool test_gzip_header();
+
+private:
+  /*
+   *  Window Size
+   *
+   *  This must be a power of two, and at least 32K for zip's deflate method
+   */
+
+	static const int WSIZE = 0x8000;
+	static const int INBUFSIZ = 0x2000;
+
+	/* If input is in memory following fields are used instead of file.  */
+	Common::DisposablePtr<Common::SeekableReadStream> _input;
+	/* The offset at which the data starts in the underlying file.  */
+	int64 _dataOffset;
+	/* The type of current block.  */
+	int _blockType;
+	/* The length of current block.  */
+	int _blockLen;
+	/* The flag of the last block.  */
+	int _lastBlock;
+	/* The flag of codes.  */
+	int _codeState;
+	/* The length of a copy.  */
+	unsigned _inflateN;
+	/* The index of a copy.  */
+	unsigned _inflateD;
+	/* The bit buffer.  */
+	unsigned long _bb;
+	/* The bits in the bit buffer.  */
+	unsigned _bk;
+	/* The sliding window in uncompressed data.  */
+	uint8 _slide[WSIZE];
+	/* Current position in the slide.  */
+	unsigned _wp;
+	/* The literal/length code table.  */
+	struct huft *_tl;
+	/* The distance code table.  */
+	struct huft *_td;
+	/* The lookup bits for the literal/length code table. */
+	int _bl;
+	/* The lookup bits for the distance code table.  */
+	int _bd;
+	/* The original offset value.  */
+	int64 _savedOffset;
+
+	bool _err;
+
+	/* The input buffer.  */
+	byte _inbuf[INBUFSIZ];
+	int _inbufD;
+	int _inbufSize;
+	uint64 _uncompressedSize;
+	uint64 _streamPos;
+	bool _eos;
+
+	void inflate_window();
+	void get_new_block();
+	byte parentGetByte();
+	void parentSeek(int64 off);
+	void init_fixed_block();
+	int inflate_codes_in_window();
+	void init_dynamic_block ();
+	void init_stored_block ();
+	int32 readAtOffset(int64 offset, byte *buf, uint32 len);
+};
+
 byte
 GzioReadStream::parentGetByte ()
 {
@@ -932,6 +1033,13 @@ GzioReadStream::inflate_window ()
 	  if (_lastBlock)
 	    break;
 
+	  if (_inbufD == _inbufSize && _input->eos())
+	    {
+	      /* No buffer anymore on a block boundary */
+	      _lastBlock = true;
+	      break;
+	    }
+
 	  get_new_block ();
 	}
 
@@ -1043,8 +1151,87 @@ GzioReadStream::test_zlib_header ()
       return false;
     }
 
-  _dataOffset = 2;
+  _dataOffset += 2;
+
+  return true;
+}
+
+bool
+GzioReadStream::test_gzip_header ()
+{
+  uint8 hdr[2];
+  uint8 cm, flg;
+
+  hdr[0] = parentGetByte ();
+  hdr[1] = parentGetByte ();
+  if (hdr[0] != 0x1F || hdr[1] != 0x8B)
+    {
+      return false;
+    }
+
+  cm = parentGetByte ();
+  /* Check that compression method is DEFLATE.  */
+  if (cm != GZ_DEFLATED)
+    {
+      return false;
+    }
+
+  flg = parentGetByte ();
+
+  // time
+  parentGetByte ();
+  parentGetByte ();
+  parentGetByte ();
+  parentGetByte ();
+
+  // XFL & OS
+  parentGetByte ();
+  parentGetByte ();
+
+  _dataOffset += 10;
+
+  // Invalid flags set
+  if (flg & GZ_RESERVED)
+    {
+      return false;
+    }
+
+  // Extra field
+  if (flg & GZ_EXTRA_FIELD)
+    {
+      uint16 xlen = parentGetByte () << 8;
+      xlen |= parentGetByte ();
+      _dataOffset += 2;
+      while (xlen--)
+        {
+	  parentGetByte ();
+          _dataOffset++;
+	}
+    }
+
+  // File name
+  if (flg & GZ_ORIG_NAME)
+    {
+      while (parentGetByte ())
+        _dataOffset++;
+      _dataOffset++;
+    }
 
+  // Comment
+  if (flg & GZ_COMMENT)
+    {
+      while (parentGetByte ())
+        _dataOffset++;
+      _dataOffset++;
+    }
+
+  // CRC
+  if (flg & GZ_CRC)
+    {
+      parentGetByte ();
+      parentGetByte ();
+      _dataOffset += 2;
+    }
   return true;
 }
 
@@ -1055,7 +1242,7 @@ GzioReadStream::readAtOffset (int64 offset, byte *buf, uint32 len)
 
   /* Do we reset decompression to the beginning of the file?  */
   if (_savedOffset > offset + WSIZE)
-    initialize_tables ();
+    initialize_tables();
 
   /*
    *  This loop operates upon uncompressed data only.  The only
@@ -1098,13 +1285,6 @@ GzioReadStream::readAtOffset (int64 offset, byte *buf, uint32 len)
 }
 
 uint32 GzioReadStream::read(void *dataPtr, uint32 dataSize) {
-	bool maybeEos = false;
-	// Read at most as many bytes as are still available...
-	if (dataSize > _uncompressedSize - _streamPos) {
-		dataSize = _uncompressedSize - _streamPos;
-		maybeEos = true;
-	}
-
 	int32 actualRead = readAtOffset(_streamPos, (byte *)dataPtr, dataSize);
 	if (actualRead < 0) {
 		_err = true;
@@ -1113,7 +1293,7 @@ uint32 GzioReadStream::read(void *dataPtr, uint32 dataSize) {
 
 	_streamPos += actualRead;
 
-	if (maybeEos &&	actualRead == (int32)dataSize)
+	if (_lastBlock && (uint32)actualRead < dataSize)
 		_eos = true;
 
 	return actualRead;
@@ -1121,9 +1301,10 @@ uint32 GzioReadStream::read(void *dataPtr, uint32 dataSize) {
 
 bool GzioReadStream::seek(int64 offs, int whence) {
 	// Pre-Condition
-	assert(_streamPos <= _uncompressedSize);
+	assert(_uncompressedSize == 0 || _streamPos <= _uncompressedSize);
 	switch (whence) {
 	case SEEK_END:
+		assert(_uncompressedSize != 0);
 		_streamPos = _uncompressedSize + offs;
 		break;
 	case SEEK_SET:
@@ -1136,71 +1317,133 @@ bool GzioReadStream::seek(int64 offs, int whence) {
 		break;
 	}
 	// Post-Condition
-	assert(_streamPos <= _uncompressedSize);
+	assert(_uncompressedSize == 0 || _streamPos <= _uncompressedSize);
 
 	// Reset end-of-stream flag on a successful seek
 	_eos = false;
 	return true;
 }
 
-GzioReadStream* GzioReadStream::openDeflate(Common::SeekableReadStream *parent, uint64 uncompressed_size, DisposeAfterUse::Flag disposeParent)
-{
-  GzioReadStream *gzio = new GzioReadStream(parent, disposeParent, uncompressed_size, GzioReadStream::Mode::ZLIB);
+#ifndef USE_ZLIB
+SeekableReadStream* wrapCompressedReadStream(Common::SeekableReadStream *parent, DisposeAfterUse::Flag disposeParent, uint64 knownSize) {
+	if (!parent)
+		return nullptr;
 
-  gzio->initialize_tables ();
+	if (parent->eos() || parent->err() || parent->size() < 2) {
+		if (disposeParent == DisposeAfterUse::YES) {
+			delete parent;
+		}
+		return nullptr;
+	}
 
-  return gzio;
-}
+	uint16 header = parent->readUint16BE();
+	bool isCompressed = (header == 0x1F8B ||
+			     ((header & 0x0F00) == 0x0800 &&
+			      header % 31 == 0));
+	parent->seek(-2, SEEK_CUR);
+	if (!isCompressed) {
+		return parent;
+	}
 
-GzioReadStream* GzioReadStream::openClickteam(Common::SeekableReadStream *parent, uint64 uncompressed_size, DisposeAfterUse::Flag disposeParent)
-{
-  GzioReadStream *gzio = new GzioReadStream(parent, disposeParent, uncompressed_size, GzioReadStream::Mode::CLICKTEAM);
+	// Read gzip footer
+	if (header == 0x1F8B) {
+		uint64 pos = parent->pos();
+		// Retrieve the original file size
+		parent->seek(-4, SEEK_END);
+		knownSize = parent->readUint32LE();
+		parent->seek(pos, SEEK_SET);
+	}
+
+	GzioReadStream* gzio = new GzioReadStream(parent, disposeParent, knownSize, GzioReadStream::Mode::ZLIB);
 
-  gzio->initialize_tables ();
+	if (header == 0x1F8B) {
+		if (!gzio->test_gzip_header()) {
+			delete gzio;
+			return nullptr;
+		}
+	} else {
+		if (!gzio->test_zlib_header()) {
+			delete gzio;
+			return nullptr;
+		}
+	}
 
-  return gzio;
+	gzio->initialize_tables();
+	return gzio;
 }
 
-GzioReadStream* GzioReadStream::openZlib(Common::SeekableReadStream *parent, uint64 uncompressed_size, DisposeAfterUse::Flag disposeParent)
-{
-  GzioReadStream* gzio = new GzioReadStream(parent, disposeParent, uncompressed_size, GzioReadStream::Mode::ZLIB);
+SeekableReadStream* wrapDeflateReadStream(Common::SeekableReadStream *parent, DisposeAfterUse::Flag disposeParent, uint64 knownSize, const byte *dict, uint dictLen) {
+	if (!parent)
+		return nullptr;
 
-  if (!gzio->test_zlib_header())
-    {
-      delete gzio;
-      return nullptr;
-    }
+	GzioReadStream *gzio = new GzioReadStream(parent, disposeParent, knownSize, GzioReadStream::Mode::ZLIB, dict, dictLen);
+	gzio->initialize_tables();
 
-  gzio->initialize_tables();
+	return gzio;
+}
 
-  return gzio;
+WriteStream *wrapCompressedWriteStream(WriteStream *toBeWrapped) {
+	// Not supported, return stream itself to write uncompressed data
+	return toBeWrapped;
 }
 
-int32
-GzioReadStream::clickteamDecompress (byte *outbuf, uint32 outsize, byte *inbuf, uint32 insize, int64 off)
-{
-  Common::ScopedPtr<GzioReadStream> gzio(GzioReadStream::openClickteam(new Common::MemoryReadStream(inbuf, insize, DisposeAfterUse::NO), outsize + off, DisposeAfterUse::YES));
-  if (!gzio)
-    return -1;
-  return gzio->readAtOffset(off, outbuf, outsize);
+bool inflateZlib(byte *dst, unsigned long *dstLen, const byte *src, unsigned long srcLen) {
+	Common::ScopedPtr<Common::SeekableReadStream> gzio(wrapCompressedReadStream(new Common::MemoryReadStream(src, srcLen, DisposeAfterUse::NO), DisposeAfterUse::YES, 0));
+	if (!gzio)
+		return false;
+	uint32 readLen = gzio->read(dst, *dstLen);
+	if (readLen == *dstLen && !gzio->eos()) {
+		// Make sure we are at the end by forcing EOS (simulate Z_BUF_ERROR)
+		byte chk;
+		gzio->read(&chk, sizeof(chk));
+	}
+	*dstLen = readLen;
+	return !gzio->err() && gzio->eos();
 }
 
-int32
-GzioReadStream::deflateDecompress (byte *outbuf, uint32 outsize, byte *inbuf, uint32 insize, int64 off)
-{
-  Common::ScopedPtr<GzioReadStream> gzio(GzioReadStream::openDeflate(new Common::MemoryReadStream(inbuf, insize, DisposeAfterUse::NO), outsize + off, DisposeAfterUse::YES));
-  if (!gzio)
-    return -1;
-  return gzio->readAtOffset(off, outbuf, outsize);
+bool inflateZlibHeaderless(byte *dst, uint *dstLen, const byte *src, uint srcLen, const byte *dict, uint dictLen) {
+	Common::ScopedPtr<Common::SeekableReadStream> gzio(wrapDeflateReadStream(new Common::MemoryReadStream(src, srcLen, DisposeAfterUse::NO), DisposeAfterUse::YES, 0, dict, dictLen));
+	if (!gzio)
+	    return false;
+	*dstLen = gzio->read(dst, *dstLen);
+	// In zlib version we use Z_SYNC_FLUSH so no error is raised if buffer is not completely consumed
+	return !gzio->err();
 }
 
-int32
-GzioReadStream::zlibDecompress (byte *outbuf, uint32 outsize, byte *inbuf, uint32 insize, int64 off)
-{
-  Common::ScopedPtr<GzioReadStream> gzio(GzioReadStream::openZlib(new Common::MemoryReadStream(inbuf, insize, DisposeAfterUse::NO), outsize + off, DisposeAfterUse::YES));
-  if (!gzio)
-    return -1;
-  return gzio->readAtOffset(off, outbuf, outsize);
+bool inflateZlib(Common::WriteStream *dst, Common::SeekableReadStream *src) {
+	Common::ScopedPtr<Common::SeekableReadStream> gzio(wrapCompressedReadStream(src, DisposeAfterUse::NO, 0));
+	if (!gzio)
+		return false;
+
+	byte *buffer = new byte[65536];
+	while(!gzio->eos()) {
+		uint32 readBytes = gzio->read(buffer, 65536);
+		if (gzio->err()) {
+			return false;
+		}
+		dst->write(buffer, readBytes);
+	}
+	return true;
+}
+#endif
+
+SeekableReadStream* wrapClickteamReadStream(Common::SeekableReadStream *parent, DisposeAfterUse::Flag disposeParent, uint64 uncompressed_size) {
+	if (!parent)
+		return nullptr;
+
+	GzioReadStream *gzio = new GzioReadStream(parent, disposeParent, uncompressed_size, GzioReadStream::Mode::CLICKTEAM);
+	gzio->initialize_tables();
+
+	return gzio;
+}
+
+bool inflateClickteam(byte *dst, uint *dstLen, const byte *src, uint srcLen) {
+	Common::ScopedPtr<Common::SeekableReadStream> gzio(wrapClickteamReadStream(new Common::MemoryReadStream(src, srcLen, DisposeAfterUse::NO), DisposeAfterUse::YES, 0));
+	if (!gzio)
+		return false;
+
+	*dstLen = gzio->read(dst, *dstLen);
+	return !gzio->err();
 }
 
 }
diff --git a/common/compression/gzio.h b/common/compression/gzio.h
deleted file mode 100644
index b013684f506..00000000000
--- a/common/compression/gzio.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/* gzio.c - decompression support for gzip */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2005,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * Most of this file was originally the source file "inflate.c", written
- * by Mark Adler.  It has been very heavily modified.  In particular, the
- * original would run through the whole file at once, and this version can
- * be stopped and restarted on any boundary during the decompression process.
- *
- * The license and header comments that file are included here.
- */
-
-/* inflate.c -- Not copyrighted 1992 by Mark Adler
-   version c10p1, 10 January 1993 */
-
-/* You can do whatever you like with this source file, though I would
-   prefer that if you modify it and redistribute it that you include
-   comments to that effect with your name and the date.  Thank you.
- */
-
-#include "common/scummsys.h"
-#include "common/stream.h"
-#include "common/ptr.h"
-
-namespace Common {
-
-/* The state stored in filesystem-specific data.  */
-class GzioReadStream : public Common::SeekableReadStream
-{
-public:
-	static GzioReadStream* openClickteam(Common::SeekableReadStream *parent, uint64 uncompressed_size, DisposeAfterUse::Flag disposeParent = DisposeAfterUse::NO);
-	static GzioReadStream* openDeflate(Common::SeekableReadStream *parent, uint64 uncompressed_size, DisposeAfterUse::Flag disposeParent = DisposeAfterUse::NO);
-	static GzioReadStream* openZlib(Common::SeekableReadStream *parent, uint64 uncompressed_size, DisposeAfterUse::Flag disposeParent = DisposeAfterUse::NO);
-	static int32 clickteamDecompress (byte *outbuf, uint32 outsize, byte *inbuf, uint32 insize, int64 off = 0);
-	static int32 deflateDecompress (byte *outbuf, uint32 outsize, byte *inbuf, uint32 insize, int64 off = 0);
-	static int32 zlibDecompress (byte *outbuf, uint32 outsize, byte *inbuf, uint32 insize, int64 off = 0);
-	int32 readAtOffset(int64 offset, byte *buf, uint32 len);
-
-	uint32 read(void *dataPtr, uint32 dataSize) override;
-
-	bool eos() const override { return _eos; }
-	bool err() const override { return _err; }
-	void clearErr() override { _eos = false; _err = false; }
-
-	int64 pos() const override { return _streamPos; }
-	int64 size() const override { return _uncompressedSize; }
-
-	bool seek(int64 offs, int whence = SEEK_SET) override;
-
-private:
-  /*
-   *  Window Size
-   *
-   *  This must be a power of two, and at least 32K for zip's deflate method
-   */
-
-	static const int WSIZE = 0x8000;
-	static const int INBUFSIZ = 0x2000;
-
-	/* If input is in memory following fields are used instead of file.  */
-	Common::DisposablePtr<Common::SeekableReadStream> _input;
-	/* The offset at which the data starts in the underlying file.  */
-	int64 _dataOffset;
-	/* The type of current block.  */
-	int _blockType;
-	/* The length of current block.  */
-	int _blockLen;
-	/* The flag of the last block.  */
-	int _lastBlock;
-	/* The flag of codes.  */
-	int _codeState;
-	/* The length of a copy.  */
-	unsigned _inflateN;
-	/* The index of a copy.  */
-	unsigned _inflateD;
-	/* The bit buffer.  */
-	unsigned long _bb;
-	/* The bits in the bit buffer.  */
-	unsigned _bk;
-	/* The sliding window in uncompressed data.  */
-	uint8 _slide[WSIZE];
-	/* Current position in the slide.  */
-	unsigned _wp;
-	/* The literal/length code table.  */
-	struct huft *_tl;
-	/* The distance code table.  */
-	struct huft *_td;
-	/* The lookup bits for the literal/length code table. */
-	int _bl;
-	/* The lookup bits for the distance code table.  */
-	int _bd;
-	/* The original offset value.  */
-	int64 _savedOffset;
-
-	bool _err;
-
-	/* The input buffer.  */
-	byte _inbuf[INBUFSIZ];
-	int _inbufD;
-	int _inbufSize;
-	uint64 _uncompressedSize;
-	uint64 _streamPos;
-	bool _eos;
-
-	enum class Mode { ZLIB, CLICKTEAM } _mode;
-
-        GzioReadStream(Common::SeekableReadStream *parent, DisposeAfterUse::Flag disposeParent, uint64 uncompressedSize, Mode mode) :
-	  _dataOffset(0), _blockType(0), _blockLen(0),
-	  _lastBlock(0), _codeState (0), _inflateN(0),
-	  _inflateD(0), _bb(0), _bk(0), _wp(0), _tl(nullptr),
-	  _td(nullptr), _bl(0),
-	  _bd(0), _savedOffset(0), _err(false), _mode(mode), _input(parent, disposeParent),
-	  _inbufD(0), _inbufSize(0), _uncompressedSize(uncompressedSize), _streamPos(0), _eos(false) {}
-
-	void inflate_window();
-	void initialize_tables();
-	bool test_zlib_header();
-	void get_new_block();
-	byte parentGetByte();
-	void parentSeek(int64 off);
-	void init_fixed_block();
-	int inflate_codes_in_window();
-	void init_dynamic_block ();
-	void init_stored_block ();
-};
-
-}
diff --git a/common/compression/installshield_cab.cpp b/common/compression/installshield_cab.cpp
index 2535e7497b4..4ff50d54749 100644
--- a/common/compression/installshield_cab.cpp
+++ b/common/compression/installshield_cab.cpp
@@ -49,12 +49,39 @@
 #include "common/memstream.h"
 #include "common/substream.h"
 #include "common/ptr.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 namespace Common {
 
 namespace {
 
+bool inflateZlibInstallShield(byte *dst, uint dstLen, const byte *src, uint srcLen) {
+	if (!dst || !dstLen || !src || !srcLen)
+		return false;
+
+	// See if we have sync bytes. If so, just use our function for that.
+	if (srcLen >= 4 && READ_BE_UINT32(src + srcLen - 4) == 0xFFFF)
+		return inflateZlibHeaderless(dst, &dstLen, src, srcLen);
+
+	// Otherwise, we have some custom code we get to use here.
+
+	uint32 bytesRead = 0, bytesProcessed = 0;
+	while (dstLen > 0 && bytesRead < srcLen) {
+		uint16 chunkSize = READ_LE_UINT16(src + bytesRead);
+		bytesRead += 2;
+
+		uint zlibLen = dstLen;
+		if (!inflateZlibHeaderless(dst + bytesProcessed, &zlibLen, src + bytesRead, chunkSize)) {
+			return false;
+		}
+
+		bytesProcessed += zlibLen;
+		dstLen -= zlibLen;
+		bytesRead += chunkSize;
+	}
+	return true;
+}
+
 class InstallShieldCabinet : public Archive {
 public:
 	InstallShieldCabinet();
@@ -336,7 +363,6 @@ SeekableReadStream *InstallShieldCabinet::createReadStreamForMember(const Path &
 		}		
 	}
 
-#ifdef USE_ZLIB
 	byte *dst = (byte *)malloc(entry.uncompressedSize);
 
 	if (!src) {
@@ -355,11 +381,6 @@ SeekableReadStream *InstallShieldCabinet::createReadStreamForMember(const Path &
 	}
 
 	return new MemoryReadStream(dst, entry.uncompressedSize, DisposeAfterUse::YES);
-#else
-	warning("zlib required to extract compressed CAB file '%s'", name.c_str());
-	free(src);
-	return 0;
-#endif
 }
 
 bool InstallShieldCabinet::readVolumeHeader(SeekableReadStream *volumeStream, InstallShieldCabinet::VolumeHeader &inVolumeHeader) {
diff --git a/common/compression/module.mk b/common/compression/module.mk
index 55d70492403..d4620adf5b0 100644
--- a/common/compression/module.mk
+++ b/common/compression/module.mk
@@ -12,8 +12,13 @@ MODULE_OBJS := \
 	stuffit.o \
 	unarj.o \
 	unzip.o \
-	vise.o \
+	vise.o
+
+ifdef USE_ZLIB
+MODULE_OBJS += \
 	zlib.o
+endif
+
 
 # Include common rules
 include $(srcdir)/rules.mk
diff --git a/common/compression/unzip.cpp b/common/compression/unzip.cpp
index 6fa71882ed6..cc5027a4dd3 100644
--- a/common/compression/unzip.cpp
+++ b/common/compression/unzip.cpp
@@ -65,11 +65,17 @@
    PkWare has also a specification at :
       ftp://ftp.pkware.com/probdesc.zip */
 
+// Disable symbol overrides so that we can use zlib.h
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
 #include "common/scummsys.h"
 
+#ifdef USE_ZLIB
+#include <zlib.h>
+#else  // !USE_ZLIB
+
 // Even when zlib is not linked in, we can still open ZIP archives and read
-// uncompressed files from them.  Attempted decompression of compressed files
-// will result in an error.
+// files from them.  Attempted decompression of compressed files will use GZio
 //
 // Define the constants and types used by zlib.
 #define Z_ERRNO -1
@@ -83,8 +89,10 @@ typedef unsigned char Byte;
 typedef Byte Bytef;
 
 #include "common/crc.h"
+#endif
+
 #include "common/fs.h"
-#include "common/compression/gzio.h"
+#include "common/compression/deflate.h"
 #include "common/compression/unzip.h"
 #include "common/memstream.h"
 
@@ -219,7 +227,11 @@ int unzGetCurrentFileInfo(unzFile file,
    from it, and close it (you can close it before reading all the file)
    */
 
-Common::SharedArchiveContents unzOpenCurrentFile(unzFile file, const Common::CRC32& crc);
+Common::SharedArchiveContents unzOpenCurrentFile(unzFile file
+#ifndef USE_ZLIB
+		, const Common::CRC32& crc
+#endif
+		);
 /*
   Open for reading data the current file in the zipfile.
   If there is no error, the return value is UNZ_OK.
@@ -909,7 +921,11 @@ static int unzlocal_CheckCurrentFileCoherencyHeader(unz_s *s, uInt *piSizeVar,
   Open for reading data the current file in the zipfile.
   If there is no error and the file is opened, the return value is UNZ_OK.
 */
-Common::SharedArchiveContents unzOpenCurrentFile (unzFile file, const Common::CRC32 &crc) {
+Common::SharedArchiveContents unzOpenCurrentFile (unzFile file
+#ifndef USE_ZLIB
+		, const Common::CRC32 &crc
+#endif
+		) {
 	uInt iSizeVar;
 	unz_s *s;
 	uLong offset_local_extrafield;  /* offset of the local extra field */
@@ -944,7 +960,7 @@ Common::SharedArchiveContents unzOpenCurrentFile (unzFile file, const Common::CR
 	case Z_DEFLATED:
 		uncompressedBuffer = new byte[s->cur_file_info.uncompressed_size];
 		assert(s->cur_file_info.uncompressed_size == 0 || uncompressedBuffer != nullptr);
-		Common::GzioReadStream::deflateDecompress(uncompressedBuffer, s->cur_file_info.uncompressed_size, compressedBuffer, s->cur_file_info.compressed_size);
+		Common::inflateZlibHeaderless(uncompressedBuffer, s->cur_file_info.uncompressed_size, compressedBuffer, s->cur_file_info.compressed_size);
 		delete[] compressedBuffer;
 		compressedBuffer = nullptr;
 		break;
@@ -953,8 +969,11 @@ Common::SharedArchiveContents unzOpenCurrentFile (unzFile file, const Common::CR
 		delete[] compressedBuffer;
 		return Common::SharedArchiveContents();
 	}
-
+#ifndef USE_ZLIB
 	uint32 crc32_data = crc.crcFast(uncompressedBuffer, s->cur_file_info.uncompressed_size);
+#else
+	uint32 crc32_data = crc32(0, uncompressedBuffer, s->cur_file_info.uncompressed_size);
+#endif
 	if (crc32_data != crc32_wait) {
 		delete[] uncompressedBuffer;
 		warning("CRC32 mismatch: %08x, %08x", crc32_data, crc32_wait);
@@ -970,7 +989,9 @@ namespace Common {
 
 class ZipArchive : public MemcachingCaseInsensitiveArchive {
 	unzFile _zipFile;
+#ifndef USE_ZLIB
 	Common::CRC32 _crc;
+#endif
 	bool _flattenTree;
 
 public:
@@ -1006,7 +1027,7 @@ public:
 };
 */
 
-ZipArchive::ZipArchive(unzFile zipFile, bool flattenTree) : _zipFile(zipFile), _crc(), _flattenTree(flattenTree) {
+ZipArchive::ZipArchive(unzFile zipFile, bool flattenTree) : _zipFile(zipFile), _flattenTree(flattenTree) {
 	assert(_zipFile);
 }
 
@@ -1043,8 +1064,11 @@ const ArchiveMemberPtr ZipArchive::getMember(const Path &path) const {
 Common::SharedArchiveContents ZipArchive::readContentsForPath(const Common::String& name) const {
 	if (unzLocateFile(_zipFile, name.c_str(), 2) != UNZ_OK)
 		return Common::SharedArchiveContents();
-
+#ifndef USE_ZLIB
 	return unzOpenCurrentFile(_zipFile, _crc);
+#else
+	return unzOpenCurrentFile(_zipFile);
+#endif
 }
 
 Archive *makeZipArchive(const String &name, bool flattenTree) {
diff --git a/common/compression/vise.cpp b/common/compression/vise.cpp
index 0b107bee892..649c1fd81c7 100644
--- a/common/compression/vise.cpp
+++ b/common/compression/vise.cpp
@@ -23,7 +23,7 @@
 
 #include "common/macresman.h"
 #include "common/memstream.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 // Installer VISE archive loader.
 //
@@ -188,14 +188,10 @@ Common::SeekableReadStream *MacVISEArchive::ArchiveMember::createReadStream() co
 	//
 	// If this turns out to be significant, then this will need to be updated to pass information to the deflate decompressor to
 	// handle the non-standard behavior.
-#if defined(USE_ZLIB)
 	if (!Common::inflateZlibHeaderless(decompressedData, uncompressedSize, &compressedData[0], compressedSize)) {
 		free(decompressedData);
 		return nullptr;
 	}
-#else
-	return nullptr;
-#endif
 
 	return new Common::MemoryReadStream(decompressedData, uncompressedSize, DisposeAfterUse::YES);
 }
diff --git a/common/compression/zlib.cpp b/common/compression/zlib.cpp
index 0d3d06cc6a4..61e35696e4e 100644
--- a/common/compression/zlib.cpp
+++ b/common/compression/zlib.cpp
@@ -19,41 +19,35 @@
  *
  */
 
-// Disable symbol overrides so that we can use zlib.h
-#define FORBIDDEN_SYMBOL_ALLOW_ALL
+#ifdef __MORPHOS__
+  #define _NO_PPCINLINE
+  #include <zlib.h>
+  #undef _NO_PPCINLINE
+#else
+  #include <zlib.h>
+#endif
+
+#if ZLIB_VERNUM < 0x1204
+#error Version 1.2.0.4 or newer of zlib is required for this code
+#endif
+
+#include "common/compression/deflate.h"
 
-#include "common/compression/zlib.h"
 #include "common/ptr.h"
 #include "common/util.h"
 #include "common/stream.h"
 #include "common/debug.h"
 #include "common/textconsole.h"
 
-#if defined(USE_ZLIB)
-  #ifdef __MORPHOS__
-	#define _NO_PPCINLINE
-	#include <zlib.h>
-	#undef _NO_PPCINLINE
-  #else
-	#include <zlib.h>
-  #endif
-
-  #if ZLIB_VERNUM < 0x1204
-  #error Version 1.2.0.4 or newer of zlib is required for this code
-  #endif
-#endif
-
 
 namespace Common {
 
-#if defined(USE_ZLIB)
-
-bool uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long srcLen) {
-	return Z_OK == ::uncompress(dst, dstLen, src, srcLen);
+bool inflateZlib(byte *dst, unsigned long *dstLen, const byte *src, unsigned long srcLen) {
+	return Z_OK == uncompress(dst, dstLen, src, srcLen);
 }
 
-bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen, const byte *dict, uint dictLen) {
-	if (!dst || !dstLen || !src || !srcLen)
+bool inflateZlibHeaderless(byte *dst, uint *dstLen, const byte *src, uint srcLen, const byte *dict, uint dictLen) {
+	if (!dst || !dstLen || !*dstLen || !src || !srcLen)
 		return false;
 
 	// Initialize zlib
@@ -61,7 +55,7 @@ bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen,
 	stream.next_in = const_cast<byte *>(src);
 	stream.avail_in = srcLen;
 	stream.next_out = dst;
-	stream.avail_out = dstLen;
+	stream.avail_out = *dstLen;
 	stream.zalloc = Z_NULL;
 	stream.zfree = Z_NULL;
 	stream.opaque = Z_NULL;
@@ -85,6 +79,7 @@ bool inflateZlibHeaderless(byte *dst, uint dstLen, const byte *src, uint srcLen,
 	}
 
 	inflateEnd(&stream);
+	*dstLen = *dstLen - stream.avail_out;
 	return true;
 }
 
@@ -92,56 +87,6 @@ enum {
 	kTempBufSize = 65536
 };
 
-bool inflateZlibInstallShield(byte *dst, uint dstLen, const byte *src, uint srcLen) {
-	if (!dst || !dstLen || !src || !srcLen)
-		return false;
-
-	// See if we have sync bytes. If so, just use our function for that.
-	if (srcLen >= 4 && READ_BE_UINT32(src + srcLen - 4) == 0xFFFF)
-		return inflateZlibHeaderless(dst, dstLen, src, srcLen);
-
-	// Otherwise, we have some custom code we get to use here.
-
-	byte *temp = (byte *)malloc(kTempBufSize);
-
-	uint32 bytesRead = 0, bytesProcessed = 0;
-	while (bytesRead < srcLen) {
-		uint16 chunkSize = READ_LE_UINT16(src + bytesRead);
-		bytesRead += 2;
-
-		// Initialize zlib
-		z_stream stream;
-		stream.next_in = const_cast<byte *>(src + bytesRead);
-		stream.avail_in = chunkSize;
-		stream.next_out = temp;
-		stream.avail_out = kTempBufSize;
-		stream.zalloc = Z_NULL;
-		stream.zfree = Z_NULL;
-		stream.opaque = Z_NULL;
-
-		// Negative MAX_WBITS tells zlib there's no zlib header
-		int err = inflateInit2(&stream, -MAX_WBITS);
-		if (err != Z_OK)
-			return false;
-
-		err = inflate(&stream, Z_FINISH);
-		if (err != Z_OK && err != Z_STREAM_END) {
-			inflateEnd(&stream);
-			free(temp);
-			return false;
-		}
-
-		memcpy(dst + bytesProcessed, temp, stream.total_out);
-		bytesProcessed += stream.total_out;
-
-		inflateEnd(&stream);
-		bytesRead += chunkSize;
-	}
-
-	free(temp);
-	return true;
-}
-
 bool inflateZlib(Common::WriteStream *dst, Common::SeekableReadStream *src) {
 	byte *inBuffer, *outBuffer;
 	z_stream stream;
@@ -232,7 +177,7 @@ protected:
 
 	byte	_buf[BUFSIZE];
 
-	ScopedPtr<SeekableReadStream> _wrapped;
+	DisposablePtr<SeekableReadStream> _wrapped;
 	z_stream _stream;
 	int _zlibErr;
 	uint64 _parentPos;
@@ -242,7 +187,7 @@ protected:
 
 public:
 
-	GZipReadStream(SeekableReadStream *w, uint32 knownSize = 0) : _wrapped(w), _stream() {
+	GZipReadStream(SeekableReadStream *w, DisposeAfterUse::Flag disposeParent, uint32 knownSize) : _wrapped(w, disposeParent), _stream() {
 		assert(w != nullptr);
 
 		_parentPos = w->pos();
@@ -278,6 +223,33 @@ public:
 		_stream.avail_in = 0;
 	}
 
+	GZipReadStream(SeekableReadStream *w, DisposeAfterUse::Flag disposeParent, uint32 knownSize, const byte *dict, uint dictLen) : _wrapped(w, disposeParent), _stream() {
+		assert(w != nullptr);
+
+		_parentPos = w->pos();
+		// This is headerless deflate
+		// Original size not available
+		// use an otherwise known size if supplied.
+		_origSize = knownSize;
+		_pos = 0;
+		_eos = false;
+
+		_zlibErr = inflateInit2(&_stream, -MAX_WBITS);
+		if (_zlibErr != Z_OK)
+			return;
+
+		// Set the dictionary, if provided
+		if (dict != nullptr && dictLen > 0) {
+			_zlibErr = inflateSetDictionary(&_stream, const_cast<byte *>(dict), dictLen);
+			if (_zlibErr != Z_OK)
+				return;
+		}
+
+		// Setup input buffer
+		_stream.next_in = _buf;
+		_stream.avail_in = 0;
+	}
+
 	~GZipReadStream() {
 		inflateEnd(&_stream);
 	}
@@ -488,38 +460,47 @@ public:
 	int64 pos() const override { return _pos; }
 };
 
-#endif	// USE_ZLIB
+SeekableReadStream *wrapCompressedReadStream(SeekableReadStream *toBeWrapped, DisposeAfterUse::Flag disposeParent, uint64 knownSize) {
+	if (!toBeWrapped) {
+		return nullptr;
+	}
 
-SeekableReadStream *wrapCompressedReadStream(SeekableReadStream *toBeWrapped, uint32 knownSize) {
-	if (toBeWrapped) {
-		if (toBeWrapped->eos() || toBeWrapped->err() || toBeWrapped->size() < 2) {
+	if (toBeWrapped->eos() || toBeWrapped->err() || toBeWrapped->size() < 2) {
+		if (disposeParent == DisposeAfterUse::YES) {
 			delete toBeWrapped;
-			return nullptr;
 		}
-		uint16 header = toBeWrapped->readUint16BE();
-		bool isCompressed = (header == 0x1F8B ||
-				     ((header & 0x0F00) == 0x0800 &&
-				      header % 31 == 0));
-		toBeWrapped->seek(-2, SEEK_CUR);
-		if (isCompressed) {
-#if defined(USE_ZLIB)
-			return new GZipReadStream(toBeWrapped, knownSize);
-#else
+		return nullptr;
+	}
+
+	uint16 header = toBeWrapped->readUint16BE();
+	bool isCompressed = (header == 0x1F8B ||
+			     ((header & 0x0F00) == 0x0800 &&
+			      header % 31 == 0));
+	toBeWrapped->seek(-2, SEEK_CUR);
+	if (isCompressed) {
+		return new GZipReadStream(toBeWrapped, disposeParent, knownSize);
+	}
+	return toBeWrapped;
+}
+
+SeekableReadStream *wrapDeflateReadStream(SeekableReadStream *toBeWrapped, DisposeAfterUse::Flag disposeParent, uint64 knownSize, const byte *dict, uint dictLen) {
+	if (!toBeWrapped) {
+		return nullptr;
+	}
+
+	if (toBeWrapped->eos() || toBeWrapped->err()) {
+		if (disposeParent == DisposeAfterUse::YES) {
 			delete toBeWrapped;
-			return nullptr;
-#endif
 		}
+		return nullptr;
 	}
-	return toBeWrapped;
+	return new GZipReadStream(toBeWrapped, disposeParent, knownSize, dict, dictLen);
 }
 
 WriteStream *wrapCompressedWriteStream(WriteStream *toBeWrapped) {
-#if defined(USE_ZLIB)
-	if (toBeWrapped)
-		return new GZipWriteStream(toBeWrapped);
-#endif
-	return toBeWrapped;
+	if (!toBeWrapped)
+		return nullptr;
+	return new GZipWriteStream(toBeWrapped);
 }
 
-
 } // End of namespace Common
diff --git a/common/formats/quicktime.cpp b/common/formats/quicktime.cpp
index 0fcdf4cd475..4153f517caf 100644
--- a/common/formats/quicktime.cpp
+++ b/common/formats/quicktime.cpp
@@ -34,7 +34,7 @@
 #include "common/formats/quicktime.h"
 #include "common/textconsole.h"
 #include "common/util.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 namespace Common {
 
@@ -265,7 +265,6 @@ int QuickTimeParser::readMOOV(Atom atom) {
 }
 
 int QuickTimeParser::readCMOV(Atom atom) {
-#ifdef USE_ZLIB
 	// Read in the dcom atom
 	_fd->readUint32BE();
 	if (_fd->readUint32BE() != MKTAG('d', 'c', 'o', 'm'))
@@ -290,7 +289,7 @@ int QuickTimeParser::readCMOV(Atom atom) {
 
 	// Uncompress the data
 	unsigned long dstLen = uncompressedSize;
-	if (!uncompress(uncompressedData, &dstLen, compressedData, compressedSize)) {
+	if (!inflateZlib(uncompressedData, &dstLen, compressedData, compressedSize)) {
 		warning ("Could not uncompress cmov chunk");
 		free(compressedData);
 		free(uncompressedData);
@@ -311,10 +310,6 @@ int QuickTimeParser::readCMOV(Atom atom) {
 	_fd = oldStream;
 
 	return err;
-#else
-	warning ("zlib not found, cannot read QuickTime cmov atom");
-	return -1;
-#endif
 }
 
 int QuickTimeParser::readMVHD(Atom atom) {
diff --git a/engines/agos/res.cpp b/engines/agos/res.cpp
index 0c935bbd0b7..cb1597bccbd 100644
--- a/engines/agos/res.cpp
+++ b/engines/agos/res.cpp
@@ -31,7 +31,7 @@
 #include "agos/agos.h"
 #include "agos/intern.h"
 
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 namespace AGOS {
 
@@ -62,7 +62,6 @@ uint32 AGOSEngine::readUint32Wrapper(const void *src) {
 }
 
 void AGOSEngine::decompressData(const char *srcName, byte *dst, uint32 offset, uint32 srcSize, uint32 dstSize) {
-#ifdef USE_ZLIB
 		Common::File in;
 		in.open(srcName);
 		if (in.isOpen() == false)
@@ -76,7 +75,7 @@ void AGOSEngine::decompressData(const char *srcName, byte *dst, uint32 offset, u
 				error("decompressData: Read failed");
 
 			unsigned long decompressedSize = dstSize;
-			if (!Common::uncompress(dst, &decompressedSize, srcBuffer, srcSize))
+			if (!Common::inflateZlib(dst, &decompressedSize, srcBuffer, srcSize))
 				error("decompressData: Zlib uncompress error");
 			free(srcBuffer);
 		} else {
@@ -84,9 +83,6 @@ void AGOSEngine::decompressData(const char *srcName, byte *dst, uint32 offset, u
 				error("decompressData: Read failed");
 		}
 		in.close();
-#else
-	error("Zlib support is required for Amiga and Macintosh versions");
-#endif
 }
 
 void AGOSEngine::loadOffsets(const char *filename, int number, uint32 &file, uint32 &offset, uint32 &srcSize, uint32 &dstSize) {
diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index b7a83ede48f..2f4adb9a2e1 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -26,7 +26,7 @@
 #include "common/savefile.h"
 #include "common/serializer.h"
 #include "common/system.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 #include "graphics/palette.h"
 
 #include "composer/composer.h"
diff --git a/engines/director/tests.cpp b/engines/director/tests.cpp
index e6b2907dbc8..faf3df885de 100644
--- a/engines/director/tests.cpp
+++ b/engines/director/tests.cpp
@@ -21,7 +21,7 @@
 
 #include "common/config-manager.h"
 #include "common/system.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 #include "common/memstream.h"
 #include "common/macresman.h"
diff --git a/engines/director/util.cpp b/engines/director/util.cpp
index 53b4b3b0f23..9e4f67e339e 100644
--- a/engines/director/util.cpp
+++ b/engines/director/util.cpp
@@ -25,7 +25,7 @@
 #include "common/memstream.h"
 #include "common/punycode.h"
 #include "common/tokenizer.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 #include "director/types.h"
 #include "graphics/macgui/macwindowmanager.h"
@@ -1132,12 +1132,11 @@ uint32 readVarInt(Common::SeekableReadStream &stream) {
 }
 
 Common::SeekableReadStreamEndian *readZlibData(Common::SeekableReadStream &stream, unsigned long len, unsigned long *outLen, bool bigEndian) {
-#ifdef USE_ZLIB
 	byte *in = (byte *)malloc(len);
 	byte *out = (byte *)malloc(*outLen);
 	stream.read(in, len);
 
-	if (!Common::uncompress(out, outLen, in, len)) {
+	if (!Common::inflateZlib(out, outLen, in, len)) {
 		free(in);
 		free(out);
 		return nullptr;
@@ -1145,9 +1144,6 @@ Common::SeekableReadStreamEndian *readZlibData(Common::SeekableReadStream &strea
 
 	free(in);
 	return new Common::MemoryReadStreamEndian(out, *outLen, bigEndian, DisposeAfterUse::YES);
-# else
-	return nullptr;
-# endif
 }
 
 uint16 humanVersion(uint16 ver) {
diff --git a/engines/dreamweb/rnca_archive.cpp b/engines/dreamweb/rnca_archive.cpp
index e8062644347..d90c15a4dd3 100644
--- a/engines/dreamweb/rnca_archive.cpp
+++ b/engines/dreamweb/rnca_archive.cpp
@@ -20,7 +20,7 @@
  */
 
 #include "common/array.h"
-#include "common/compression/gzio.h"
+#include "common/compression/deflate.h"
 #include "common/debug.h"
 #include "common/ptr.h"
 #include "common/substream.h"
diff --git a/engines/glk/adrift/sctaffil.cpp b/engines/glk/adrift/sctaffil.cpp
index 68dbabf4215..aad4a16fed0 100644
--- a/engines/glk/adrift/sctaffil.cpp
+++ b/engines/glk/adrift/sctaffil.cpp
@@ -23,7 +23,7 @@
 #include "glk/adrift/scprotos.h"
 #include "glk/adrift/detection.h"
 #include "common/algorithm.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 #include "common/memstream.h"
 
 namespace Glk {
@@ -390,7 +390,6 @@ static sc_bool taf_unobfuscate(sc_tafref_t taf, sc_read_callbackref_t callback,
  */
 static sc_bool taf_decompress(sc_tafref_t taf, sc_read_callbackref_t callback,
 		void *opaque, sc_bool is_gamefile) {
-#if defined(USE_ZLIB)
 	Common::SeekableReadStream *src = (Common::SeekableReadStream *)opaque;
 	assert(src);
 	Common::MemoryWriteStreamDynamic dest(DisposeAfterUse::YES);
@@ -411,9 +410,6 @@ static sc_bool taf_decompress(sc_tafref_t taf, sc_read_callbackref_t callback,
 	taf->total_in_bytes = src->pos() - startingPos;
 
 	return true;
-#else
-	return false;
-#endif
 }
 
 /*
diff --git a/engines/grim/configure.engine b/engines/grim/configure.engine
index d161b24ebf2..e5a01e70aaf 100644
--- a/engines/grim/configure.engine
+++ b/engines/grim/configure.engine
@@ -1,4 +1,4 @@
 # This file is included from the main "configure" script
 # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine grim "Grim" yes "monkey4" "Grim Fandango" "16bit highres zlib"
+add_engine grim "Grim" yes "monkey4" "Grim Fandango" "16bit highres"
 add_engine monkey4 "Escape from Monkey Island" no "" "" "bink mpeg2"
diff --git a/engines/grim/patchr.cpp b/engines/grim/patchr.cpp
index e0a61168196..6153a6dd759 100644
--- a/engines/grim/patchr.cpp
+++ b/engines/grim/patchr.cpp
@@ -22,7 +22,7 @@
 #include "common/substream.h"
 #include "common/md5.h"
 #include "common/file.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 #include "common/bufferedstream.h"
 
 #include "engines/grim/patchr.h"
diff --git a/engines/grim/resource.cpp b/engines/grim/resource.cpp
index 2300cc63adf..afb45fac94c 100644
--- a/engines/grim/resource.cpp
+++ b/engines/grim/resource.cpp
@@ -46,7 +46,7 @@
 #include "engines/grim/update/update.h"
 
 #include "common/algorithm.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 #include "common/memstream.h"
 #include "common/file.h"
 #include "common/config-manager.h"
diff --git a/engines/grim/update/mscab.cpp b/engines/grim/update/mscab.cpp
index 3c0997e946e..0d6b521bd39 100644
--- a/engines/grim/update/mscab.cpp
+++ b/engines/grim/update/mscab.cpp
@@ -24,7 +24,7 @@
 #include "common/file.h"
 #include "common/archive.h"
 #include "common/memstream.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 #include "common/str.h"
 
 namespace Grim {
@@ -210,7 +210,6 @@ MsCabinet::Decompressor::~Decompressor() {
 }
 
 bool MsCabinet::Decompressor::decompressFile(byte *&fileBuf, const FileEntry &entry) {
-#ifdef USE_ZLIB
 	// Ref: http://blogs.kde.org/node/3181
 	uint16 uncompressedLen, compressedLen;
 	byte hdrS[4];
@@ -283,10 +282,6 @@ bool MsCabinet::Decompressor::decompressFile(byte *&fileBuf, const FileEntry &en
 	fileBuf = _fileBuf;
 	_fileBuf = nullptr;
 	return true;
-#else
-	warning("zlib required to extract MSCAB");
-	return false;
-#endif
 }
 
 void MsCabinet::Decompressor::copyBlock(byte *&data_ptr) const {
diff --git a/engines/hadesch/hadesch.cpp b/engines/hadesch/hadesch.cpp
index 85130954105..d3133398be1 100644
--- a/engines/hadesch/hadesch.cpp
+++ b/engines/hadesch/hadesch.cpp
@@ -31,7 +31,7 @@
 #include "common/keyboard.h"
 #include "common/macresman.h"
 #include "common/util.h"
-#include "common/compression/gzio.h"
+#include "common/compression/deflate.h"
 #include "common/config-manager.h"
 #include "common/translation.h"
 
@@ -160,8 +160,10 @@ Common::MemoryReadStream *readWiseFile(Common::File &setupFile, const struct Wis
 	byte *uncompressedBuffer = new byte[wiseFile.uncompressedLength];
 	setupFile.seek(wiseFile.start);
 	setupFile.read(compressedBuffer, wiseFile.end - wiseFile.start - 4);
-	if (Common::GzioReadStream::deflateDecompress(uncompressedBuffer, wiseFile.uncompressedLength,
-					   compressedBuffer, wiseFile.end - wiseFile.start - 4) != (int)wiseFile.uncompressedLength) {
+
+	uint dstLen = wiseFile.uncompressedLength;
+	if (!Common::inflateZlibHeaderless(uncompressedBuffer, &dstLen,
+					   compressedBuffer, wiseFile.end - wiseFile.start - 4) || dstLen != wiseFile.uncompressedLength) {
 		debug("wise inflate failed");
 		delete[] compressedBuffer;
 		delete[] uncompressedBuffer;
diff --git a/engines/hdb/configure.engine b/engines/hdb/configure.engine
index 78ea4075543..5f735a26a9a 100644
--- a/engines/hdb/configure.engine
+++ b/engines/hdb/configure.engine
@@ -1,3 +1,3 @@
 # This file is included from the main "configure" script
 # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine hdb "Hyperspace Delivery Boy!" yes "" "" "16bit zlib highres lua"
+add_engine hdb "Hyperspace Delivery Boy!" yes "" "" "16bit highres lua"
diff --git a/engines/hdb/file-manager.cpp b/engines/hdb/file-manager.cpp
index a692c1882ca..04f697f0c83 100644
--- a/engines/hdb/file-manager.cpp
+++ b/engines/hdb/file-manager.cpp
@@ -21,7 +21,7 @@
 #include "common/debug.h"
 #include "common/file.h"
 #include "common/memstream.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 #include "hdb/hdb.h"
 #include "hdb/file-manager.h"
@@ -134,7 +134,7 @@ Common::SeekableReadStream *FileMan::findFirstData(const char *string, DataType
 
 	// Return buffer wrapped in a MemoryReadStream, automatically
 	// uncompressed if it is zlib-compressed
-	return Common::wrapCompressedReadStream(new Common::MemoryReadStream(buffer, file->length, DisposeAfterUse::YES), file->length);
+	return Common::wrapCompressedReadStream(new Common::MemoryReadStream(buffer, file->length, DisposeAfterUse::YES), DisposeAfterUse::YES, file->length);
 }
 
 int32 FileMan::getLength(const char *string, DataType type) {
diff --git a/engines/icb/configure.engine b/engines/icb/configure.engine
index 7c5a3c13914..f7f3e93c253 100644
--- a/engines/icb/configure.engine
+++ b/engines/icb/configure.engine
@@ -1,3 +1,3 @@
 # This file is included from the main "configure" script
 # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine icb "In Cold Blood" no "" "" "16bit highres zlib bink"
+add_engine icb "In Cold Blood" no "" "" "16bit highres bink"
diff --git a/engines/mtropolis/boot.cpp b/engines/mtropolis/boot.cpp
index d20fcb42bd2..2a7b99f1751 100644
--- a/engines/mtropolis/boot.cpp
+++ b/engines/mtropolis/boot.cpp
@@ -27,7 +27,6 @@
 #include "common/compression/vise.h"
 #include "common/formats/winexe.h"
 #include "common/compression/installshieldv3_archive.h"
-#include "common/compression/zlib.h"
 
 #include "graphics/maccursor.h"
 #include "graphics/wincursor.h"
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 4fd9794af48..a2a6fbd1be3 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -24,7 +24,6 @@
 #include "common/savefile.h"
 #include "common/serializer.h"
 #include "common/system.h"
-#include "common/compression/zlib.h"
 
 #include "scumm/actor.h"
 #include "scumm/charset.h"
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index 82b62efce38..15b1279f576 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -48,7 +48,7 @@
 #include "audio/decoders/raw.h"
 #include "audio/decoders/vorbis.h"
 
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 namespace Scumm {
 
@@ -800,7 +800,6 @@ void SmushPlayer::decodeFrameObject(int codec, const uint8 *src, int left, int t
 	}
 }
 
-#ifdef USE_ZLIB
 void SmushPlayer::handleZlibFrameObject(int32 subSize, Common::SeekableReadStream &b) {
 	if (_skipNext) {
 		_skipNext = false;
@@ -814,7 +813,7 @@ void SmushPlayer::handleZlibFrameObject(int32 subSize, Common::SeekableReadStrea
 
 	unsigned long decompressedSize = READ_BE_UINT32(chunkBuffer);
 	byte *fobjBuffer = (byte *)malloc(decompressedSize);
-	if (!Common::uncompress(fobjBuffer, &decompressedSize, chunkBuffer + 4, chunkSize - 4))
+	if (!Common::inflateZlib(fobjBuffer, &decompressedSize, chunkBuffer + 4, chunkSize - 4))
 		error("SmushPlayer::handleZlibFrameObject() Zlib uncompress error");
 	free(chunkBuffer);
 
@@ -829,7 +828,6 @@ void SmushPlayer::handleZlibFrameObject(int32 subSize, Common::SeekableReadStrea
 
 	free(fobjBuffer);
 }
-#endif
 
 void SmushPlayer::handleFrameObject(int32 subSize, Common::SeekableReadStream &b) {
 	assert(subSize >= 14);
@@ -877,11 +875,9 @@ void SmushPlayer::handleFrame(int32 frameSize, Common::SeekableReadStream &b) {
 		case MKTAG('F','O','B','J'):
 			handleFrameObject(subSize, b);
 			break;
-#ifdef USE_ZLIB
 		case MKTAG('Z','F','O','B'):
 			handleZlibFrameObject(subSize, b);
 			break;
-#endif
 		case MKTAG('P','S','A','D'):
 			if (!_compressedFileMode) {
 				audioChunk = (uint8 *)malloc(subSize + 8);
diff --git a/engines/scumm/smush/smush_player.h b/engines/scumm/smush/smush_player.h
index afab716feb0..de1d1c65dc8 100644
--- a/engines/scumm/smush/smush_player.h
+++ b/engines/scumm/smush/smush_player.h
@@ -238,9 +238,7 @@ private:
 	void handleAnimHeader(int32 subSize, Common::SeekableReadStream &);
 	void handleFrame(int32 frameSize, Common::SeekableReadStream &);
 	void handleNewPalette(int32 subSize, Common::SeekableReadStream &);
-#ifdef USE_ZLIB
 	void handleZlibFrameObject(int32 subSize, Common::SeekableReadStream &b);
-#endif
 	void handleFrameObject(int32 subSize, Common::SeekableReadStream &);
 	void handleSAUDChunk(uint8 *srcBuf, uint32 size, int groupId, int vol, int pan, int16 flags, int trkId, int index, int maxFrames);
 	void handleStore(int32 subSize, Common::SeekableReadStream &);
diff --git a/engines/sword25/configure.engine b/engines/sword25/configure.engine
index 33a07df6ae1..49a0b9d0721 100644
--- a/engines/sword25/configure.engine
+++ b/engines/sword25/configure.engine
@@ -1,3 +1,3 @@
 # This file is included from the main "configure" script
 # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine sword25 "Broken Sword 2.5" yes "" "" "png zlib 16bit highres lua theoradec"
+add_engine sword25 "Broken Sword 2.5" yes "" "" "png 16bit highres lua theoradec"
diff --git a/engines/sword25/kernel/persistenceservice.cpp b/engines/sword25/kernel/persistenceservice.cpp
index d0af8f2c136..8701033312e 100644
--- a/engines/sword25/kernel/persistenceservice.cpp
+++ b/engines/sword25/kernel/persistenceservice.cpp
@@ -30,7 +30,7 @@
 
 #include "common/fs.h"
 #include "common/savefile.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 #include "sword25/kernel/kernel.h"
 #include "sword25/kernel/persistenceservice.h"
 #include "sword25/kernel/inputpersistenceblock.h"
@@ -391,7 +391,7 @@ bool PersistenceService::loadGame(uint slotID) {
 
 	if (uncompressedBufferSize > curSavegameInfo.gamedataLength) {
 		// Older saved game, where the game data was compressed again.
-		if (!Common::uncompress(reinterpret_cast<byte *>(&uncompressedDataBuffer[0]), &uncompressedBufferSize,
+		if (!Common::inflateZlib(reinterpret_cast<byte *>(&uncompressedDataBuffer[0]), &uncompressedBufferSize,
 					   reinterpret_cast<byte *>(&compressedDataBuffer[0]), curSavegameInfo.gamedataLength)) {
 			error("Unable to decompress the gamedata from savegame file \"%s\".", filename.c_str());
 			delete[] uncompressedDataBuffer;
diff --git a/engines/teenagent/resources.cpp b/engines/teenagent/resources.cpp
index afce3d44a32..f14d50c4bc0 100644
--- a/engines/teenagent/resources.cpp
+++ b/engines/teenagent/resources.cpp
@@ -24,7 +24,7 @@
 #include "common/debug.h"
 #include "common/textconsole.h"
 #include "common/translation.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 namespace TeenAgent {
 
@@ -106,25 +106,6 @@ bool Resources::loadArchives(const ADGameDescription *gd) {
 	// compatibility.
 	Common::SeekableReadStream *dat = Common::wrapCompressedReadStream(dat_file);
 
-#if !defined(USE_ZLIB)
-	uint16 header = dat->readUint16BE();
-	bool isCompressed = (header == 0x1F8B ||
-				     ((header & 0x0F00) == 0x0800 &&
-				      header % 31 == 0));
-	dat->seek(-2, SEEK_CUR);
-
-	if (isCompressed) {
-		// teenagent.dat is compressed, but zlib hasn't been compiled in
-		delete dat;
-
-		const char *msg = _s("The teenagent.dat file is compressed and zlib hasn't been included in this executable. Please decompress it");
-		Common::U32String errorMessage = _(msg);
-		warning(msg);
-		GUIErrorMessage(errorMessage);
-		return false;
-	}
-#endif
-
 	dat->skip(CSEG_SIZE);
 	dseg.read(dat, DSEG_SIZE);
 	eseg.read(dat, ESEG_SIZE);
diff --git a/engines/tetraedge/te/te_free_move_zone.cpp b/engines/tetraedge/te/te_free_move_zone.cpp
index 893852539b6..39c3f161e19 100644
--- a/engines/tetraedge/te/te_free_move_zone.cpp
+++ b/engines/tetraedge/te/te_free_move_zone.cpp
@@ -22,7 +22,7 @@
 #include "tetraedge/tetraedge.h"
 
 #include "common/file.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 #include "tetraedge/te/te_free_move_zone.h"
 #include "tetraedge/te/micropather.h"
@@ -202,7 +202,7 @@ bool TeFreeMoveZone::loadAStar(const Common::Path &path, const TeVector2s32 &siz
 	byte *buf = new byte[bytes];
 	byte *outBuf = new byte[decompBytes];
 	file.read(buf, bytes);
-	bool result = Common::uncompress(outBuf, &decompBytes, buf, bytes);
+	bool result = Common::inflateZlib(outBuf, &decompBytes, buf, bytes);
 	delete [] buf;
 	if (result) {
 		for (uint i = 0; i < decompBytes; i++)
diff --git a/engines/tetraedge/te/te_model.cpp b/engines/tetraedge/te/te_model.cpp
index c5508697cf3..38d52e907e4 100644
--- a/engines/tetraedge/te/te_model.cpp
+++ b/engines/tetraedge/te/te_model.cpp
@@ -22,7 +22,7 @@
 #include "common/file.h"
 #include "common/util.h"
 #include "common/substream.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 #include "tetraedge/tetraedge.h"
 #include "tetraedge/te/te_light.h"
@@ -453,7 +453,7 @@ Common::SeekableReadStream *TeModel::tryLoadZlibStream(Common::SeekableReadStrea
 	}
 	uint32 uncompressedSize = stream.readUint32LE();
 	Common::SeekableSubReadStream *substream = new Common::SeekableSubReadStream(&stream, stream.pos(), stream.size());
-	return Common::wrapCompressedReadStream(substream, uncompressedSize);
+	return Common::wrapCompressedReadStream(substream, DisposeAfterUse::YES, uncompressedSize);
 }
 
 bool TeModel::loadWeights(Common::ReadStream &stream, Common::Array<weightElement> &weights) {
diff --git a/engines/tetraedge/te/te_model_animation.cpp b/engines/tetraedge/te/te_model_animation.cpp
index 7f98918a51d..d213253f38d 100644
--- a/engines/tetraedge/te/te_model_animation.cpp
+++ b/engines/tetraedge/te/te_model_animation.cpp
@@ -23,7 +23,7 @@
 #include "common/file.h"
 #include "common/stream.h"
 #include "common/substream.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 #include "tetraedge/tetraedge.h"
 #include "tetraedge/te/te_core.h"
diff --git a/engines/tetraedge/te/te_zlib_jpeg.cpp b/engines/tetraedge/te/te_zlib_jpeg.cpp
index 49c04bdf40b..55afd85c618 100644
--- a/engines/tetraedge/te/te_zlib_jpeg.cpp
+++ b/engines/tetraedge/te/te_zlib_jpeg.cpp
@@ -21,7 +21,7 @@
 
 #include "tetraedge/te/te_zlib_jpeg.h"
 #include "common/substream.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 namespace Tetraedge {
 
@@ -39,7 +39,7 @@ bool TeZlibJpeg::load(Common::SeekableReadStream &stream) {
 	}
 	uint32 uncompressedSize = stream.readUint32LE();
 	Common::SeekableSubReadStream *substream = new Common::SeekableSubReadStream(&stream, stream.pos(), stream.size());
-	Common::SeekableReadStream *zlibStream = Common::wrapCompressedReadStream(substream, uncompressedSize);
+	Common::SeekableReadStream *zlibStream = Common::wrapCompressedReadStream(substream, DisposeAfterUse::YES, uncompressedSize);
 	bool result = TeJpeg::load(*zlibStream);
 	delete zlibStream;
 	return result;
diff --git a/engines/titanic/configure.engine b/engines/titanic/configure.engine
index 7c9516cd4a3..66acce16814 100644
--- a/engines/titanic/configure.engine
+++ b/engines/titanic/configure.engine
@@ -1,3 +1,3 @@
 # This file is included from the main "configure" script
 # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine titanic "Starship Titanic" yes "" "" "16bit jpeg highres mad zlib"
+add_engine titanic "Starship Titanic" yes "" "" "16bit jpeg highres mad"
diff --git a/engines/titanic/support/files_manager.cpp b/engines/titanic/support/files_manager.cpp
index 04006d5cfa7..501400837e4 100644
--- a/engines/titanic/support/files_manager.cpp
+++ b/engines/titanic/support/files_manager.cpp
@@ -21,7 +21,7 @@
 
 #include "common/file.h"
 #include "common/memstream.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 #include "titanic/support/files_manager.h"
 #include "titanic/game_manager.h"
 #include "titanic/titanic.h"
diff --git a/engines/titanic/support/simple_file.h b/engines/titanic/support/simple_file.h
index 93a14d0fe22..c0dcebcbceb 100644
--- a/engines/titanic/support/simple_file.h
+++ b/engines/titanic/support/simple_file.h
@@ -26,7 +26,7 @@
 #include "titanic/support/rect.h"
 #include "common/savefile.h"
 #include "common/stream.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 #include "titanic/support/string.h"
 
 namespace Titanic {
diff --git a/engines/wintermute/base/file/base_disk_file.cpp b/engines/wintermute/base/file/base_disk_file.cpp
index 8c89d722861..b672eba729e 100644
--- a/engines/wintermute/base/file/base_disk_file.cpp
+++ b/engines/wintermute/base/file/base_disk_file.cpp
@@ -32,7 +32,7 @@
 #include "common/stream.h"
 #include "common/memstream.h"
 #include "common/file.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 #include "common/archive.h"
 #include "common/tokenizer.h"
 #include "common/config-manager.h"
@@ -221,7 +221,7 @@ Common::SeekableReadStream *openDiskFile(const Common::String &filename) {
 			file->seek(dataOffset + prefixSize, SEEK_SET);
 			file->read(compBuffer, compSize);
 
-			if (Common::uncompress(data, &uncompSize, compBuffer, compSize) != true) {
+			if (Common::inflateZlib(data, &uncompSize, compBuffer, compSize) != true) {
 				error("Error uncompressing file '%s'", filename.c_str());
 				delete[] compBuffer;
 				delete file;
diff --git a/engines/wintermute/base/file/base_file_entry.cpp b/engines/wintermute/base/file/base_file_entry.cpp
index ec242edf01d..162a7f8ee4c 100644
--- a/engines/wintermute/base/file/base_file_entry.cpp
+++ b/engines/wintermute/base/file/base_file_entry.cpp
@@ -29,7 +29,7 @@
 #include "engines/wintermute/base/file/base_package.h"
 #include "common/stream.h"
 #include "common/substream.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 namespace Wintermute {
 
@@ -42,7 +42,7 @@ Common::SeekableReadStream *BaseFileEntry::createReadStream() const {
 	bool compressed = (_compressedLength != 0);
 
 	if (compressed) {
-		file = Common::wrapCompressedReadStream(new Common::SeekableSubReadStream(file, _offset, _offset + _length, DisposeAfterUse::YES), _length); //
+		file = Common::wrapCompressedReadStream(new Common::SeekableSubReadStream(file, _offset, _offset + _compressedLength, DisposeAfterUse::YES), DisposeAfterUse::YES, _length); //
 	} else {
 		file = new Common::SeekableSubReadStream(file, _offset, _offset + _length, DisposeAfterUse::YES);
 	}
diff --git a/engines/wintermute/base/gfx/xfile_loader.cpp b/engines/wintermute/base/gfx/xfile_loader.cpp
index 12c212fe456..08bf5ea9733 100644
--- a/engines/wintermute/base/gfx/xfile_loader.cpp
+++ b/engines/wintermute/base/gfx/xfile_loader.cpp
@@ -27,7 +27,7 @@
 #include "common/endian.h"
 #include "common/str.h"
 #include "common/util.h"
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 #include "wintermute/base/gfx/xfile_loader.h"
 
@@ -714,7 +714,6 @@ bool XFileLoader::getString(char *str, uint maxLen) {
 }
 
 bool XFileLoader::decompressMsZipData() {
-#ifdef USE_ZLIB
 	bool error = false;
 
 	byte *compressedBlock = new byte[kCabInputmax];
@@ -781,7 +780,6 @@ bool XFileLoader::decompressMsZipData() {
 	}
 
 	delete[] decompressedData;
-#endif
 
 	warning("XFileLoader: decompressMsZipData: Error decompressing data!");
 	return false;
diff --git a/engines/wintermute/base/gfx/xmodel.cpp b/engines/wintermute/base/gfx/xmodel.cpp
index 9e972e44337..d6910446ac2 100644
--- a/engines/wintermute/base/gfx/xmodel.cpp
+++ b/engines/wintermute/base/gfx/xmodel.cpp
@@ -25,7 +25,7 @@
  * Copyright (c) 2003-2013 Jan Nedoma and contributors
  */
 
-#include "common/compression/zlib.h"
+#include "common/compression/deflate.h"
 
 #include "engines/wintermute/base/base_file_manager.h"
 #include "engines/wintermute/base/base_game.h"
diff --git a/engines/wintermute/configure.engine b/engines/wintermute/configure.engine
index d0f4ba34b34..60a494d9b59 100644
--- a/engines/wintermute/configure.engine
+++ b/engines/wintermute/configure.engine
@@ -1,6 +1,6 @@
 # This file is included from the main "configure" script
 # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine wintermute "Wintermute" yes "foxtail herocraft wme3d" "" "zlib 16bit highres jpeg png"
+add_engine wintermute "Wintermute" yes "foxtail herocraft wme3d" "" "16bit highres jpeg png"
 add_engine wme3d "Wintermute3D" no
 add_engine foxtail "FoxTail" yes
 add_engine herocraft "HeroCraft" yes
diff --git a/video/dxa_decoder.cpp b/video/dxa_decoder.cpp
index 37fb953383b..d0e5dcd7ff8 100644
--- a/video/dxa_decoder.cpp
+++ b/video/dxa_decoder.cpp
@@ -31,7 +31,7 @@
 
 #include "audio/decoders/wave.h"
 
-#include "common/compression/gzio.h"
+#include "common/compression/deflate.h"
 
 namespace Video {
 
@@ -176,7 +176,7 @@ void DXADecoder::DXAVideoTrack::setFrameStartPos() {
 }
 
 void DXADecoder::DXAVideoTrack::decodeZlib(byte *data, int size, int totalSize) {
-	Common::GzioReadStream::zlibDecompress(data, totalSize, _inBuffer, size);
+	Common::inflateZlib(data, totalSize, _inBuffer, size);
 }
 
 #define BLOCKW 4


Commit: 7c9df6c2bfbd9f0290f1e7f870800212ea0aba90
    https://github.com/scummvm/scummvm/commit/7c9df6c2bfbd9f0290f1e7f870800212ea0aba90
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-08-28T21:49:03+02:00

Commit Message:
GLK: ADRIFT: Use wrapCompressedReadStream instead of specific function

Changed paths:
    engines/glk/adrift/sctaffil.cpp


diff --git a/engines/glk/adrift/sctaffil.cpp b/engines/glk/adrift/sctaffil.cpp
index aad4a16fed0..6846b96d3f3 100644
--- a/engines/glk/adrift/sctaffil.cpp
+++ b/engines/glk/adrift/sctaffil.cpp
@@ -395,8 +395,19 @@ static sc_bool taf_decompress(sc_tafref_t taf, sc_read_callbackref_t callback,
 	Common::MemoryWriteStreamDynamic dest(DisposeAfterUse::YES);
 	size_t startingPos = src->pos();
 
-	if (!Common::inflateZlib(&dest, src))
+	Common::SeekableReadStream *gzStream = wrapCompressedReadStream(src, DisposeAfterUse::NO);
+	if (!gzStream) {
 		return false;
+	}
+
+	dest.writeStream(gzStream);
+
+	if (!gzStream->eos() || gzStream->err()) {
+		delete gzStream;
+		return false;
+	}
+
+	delete gzStream;
 
 	// Iterate through pushing data out to the taf file
 	const byte *pTemp = dest.getData();


Commit: 2f7c2149e5b3e8e0e7912a387ea80413e8b1341d
    https://github.com/scummvm/scummvm/commit/2f7c2149e5b3e8e0e7912a387ea80413e8b1341d
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-08-28T21:49:03+02:00

Commit Message:
COMMON: Remove useless inflateZlib function

To write on stream it's simpler to use wrapCompressedReadStream and
writeStream function.

Changed paths:
    common/compression/deflate.h
    common/compression/gzio.cpp
    common/compression/zlib.cpp


diff --git a/common/compression/deflate.h b/common/compression/deflate.h
index 5e655c19314..216ea75fc07 100644
--- a/common/compression/deflate.h
+++ b/common/compression/deflate.h
@@ -112,18 +112,6 @@ static inline bool inflateClickteam(byte *dst, uint  dstLen, const byte *src, ui
 	return inflateClickteam(dst, &dstLen, src, srcLen);
 }
 
-/**
- * Wrapper around zlib's inflate functions. This function is used by Glk to
- * decompress TAF 4.0 files, which are 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 inflateZlib(Common::WriteStream *dst, Common::SeekableReadStream *src);
-
 /**
  * Take an arbitrary SeekableReadStream and wrap it in a custom stream which
  * provides transparent on-the-fly decompression. Assumes the data it
diff --git a/common/compression/gzio.cpp b/common/compression/gzio.cpp
index f7e849bf6f5..d5758e8974c 100644
--- a/common/compression/gzio.cpp
+++ b/common/compression/gzio.cpp
@@ -1409,22 +1409,6 @@ bool inflateZlibHeaderless(byte *dst, uint *dstLen, const byte *src, uint srcLen
 	// In zlib version we use Z_SYNC_FLUSH so no error is raised if buffer is not completely consumed
 	return !gzio->err();
 }
-
-bool inflateZlib(Common::WriteStream *dst, Common::SeekableReadStream *src) {
-	Common::ScopedPtr<Common::SeekableReadStream> gzio(wrapCompressedReadStream(src, DisposeAfterUse::NO, 0));
-	if (!gzio)
-		return false;
-
-	byte *buffer = new byte[65536];
-	while(!gzio->eos()) {
-		uint32 readBytes = gzio->read(buffer, 65536);
-		if (gzio->err()) {
-			return false;
-		}
-		dst->write(buffer, readBytes);
-	}
-	return true;
-}
 #endif
 
 SeekableReadStream* wrapClickteamReadStream(Common::SeekableReadStream *parent, DisposeAfterUse::Flag disposeParent, uint64 uncompressed_size) {
diff --git a/common/compression/zlib.cpp b/common/compression/zlib.cpp
index 61e35696e4e..f52e3f3984d 100644
--- a/common/compression/zlib.cpp
+++ b/common/compression/zlib.cpp
@@ -83,83 +83,6 @@ bool inflateZlibHeaderless(byte *dst, uint *dstLen, const byte *src, uint srcLen
 	return true;
 }
 
-enum {
-	kTempBufSize = 65536
-};
-
-bool inflateZlib(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




More information about the Scummvm-git-logs mailing list