[Scummvm-git-logs] scummvm master -> a6204314fd2c9d95f282a7558285e417ff1ee4c9

elasota noreply at scummvm.org
Sun Jun 26 00:25:21 UTC 2022


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

Summary:
a6204314fd MTROPOLIS: Add support for QuickTime-compressed mToons


Commit: a6204314fd2c9d95f282a7558285e417ff1ee4c9
    https://github.com/scummvm/scummvm/commit/a6204314fd2c9d95f282a7558285e417ff1ee4c9
Author: elasota (ejlasota at gmail.com)
Date: 2022-06-25T20:21:23-04:00

Commit Message:
MTROPOLIS: Add support for QuickTime-compressed mToons

Changed paths:
    engines/mtropolis/assets.cpp
    engines/mtropolis/assets.h
    engines/mtropolis/data.h


diff --git a/engines/mtropolis/assets.cpp b/engines/mtropolis/assets.cpp
index a9d62472261..192ff0c97e1 100644
--- a/engines/mtropolis/assets.cpp
+++ b/engines/mtropolis/assets.cpp
@@ -25,6 +25,9 @@
 #include "audio/audiostream.h"
 
 #include "common/endian.h"
+#include "common/memstream.h"
+
+#include "image/codecs/codec.h"
 
 #include "mtropolis/assets.h"
 #include "mtropolis/asset_factory.h"
@@ -160,8 +163,10 @@ void CachedMToon::decompressFrames(const Common::Array<uint8> &data) {
 	for (size_t i = 0; i < numFrames; i++) {
 		if (_metadata->codecID == kMToonRLECodecID) {
 			decompressRLEFrame(i);
-		} else {
+		} else if (_metadata->codecID == 0) {
 			loadUncompressedFrame(data, i);
+		} else {
+			decompressQuickTimeFrame(data, i);
 		}
 	}
 
@@ -423,6 +428,46 @@ void CachedMToon::loadUncompressedFrame(const Common::Array<uint8> &data, size_t
 	_decompressedFrames[frameIndex] = surface;
 }
 
+void CachedMToon::decompressQuickTimeFrame(const Common::Array<uint8> &data, size_t frameIndex) {
+	const MToonMetadata::FrameDef &frameDef = _metadata->frames[frameIndex];
+	uint16 stride = frameDef.decompressedBytesPerRow;
+
+	uint16 bpp = _metadata->bitsPerPixel;
+	size_t w = frameDef.rect.width();
+	size_t h = frameDef.rect.height();
+
+	if (_metadata->codecData.size() < 86) {
+		error("Unknown codec data block size");
+	}
+	if (READ_BE_UINT16(&_metadata->codecData[32]) != w || READ_BE_UINT16(&_metadata->codecData[34]) != h || READ_BE_UINT16(&_metadata->codecData[82]) != bpp) {
+		error("Codec data block didn't match mToon metadata");
+	}
+
+	Image::Codec *codec = Image::createQuickTimeCodec(_metadata->codecID, w, h, bpp);
+	if (!codec) {
+		error("Unknown QuickTime codec for mToon frame");
+	}
+
+	if (frameDef.dataOffset > data.size())
+		error("Invalid framedef offset");
+
+	if (frameDef.compressedSize > data.size())
+		error("Invalid compressed size");
+
+	if (frameDef.compressedSize - data.size() < frameDef.dataOffset)
+		error("Not enough available bytes for compressed data");
+
+	Common::MemoryReadStream stream(&data[frameDef.dataOffset], frameDef.compressedSize);
+
+	const Graphics::Surface *surface = codec->decodeFrame(stream);
+	if (!surface) {
+		error("mToon QuickTime frame failed to decompress");
+	}
+
+	// Clone the decompressed frame
+	_decompressedFrames[frameIndex] = Common::SharedPtr<Graphics::Surface>(new Graphics::Surface(*surface));
+}
+
 template<class TSrcNumber, uint32 TSrcLiteralMask, uint32 TSrcTransparentSkipMask, class TDestNumber, uint32 TDestLiteralMask, uint32 TDestTransparentSkipMask>
 void CachedMToon::rleReformat(RleFrame &frame, const Common::Array<TSrcNumber> &srcData, const Graphics::PixelFormat &srcFormatRef, Common::Array<TDestNumber> &destData, const Graphics::PixelFormat &destFormatRef) {
 	const Graphics::PixelFormat srcFormat = srcFormatRef;
diff --git a/engines/mtropolis/assets.h b/engines/mtropolis/assets.h
index e8401b58f18..7a06c3aae25 100644
--- a/engines/mtropolis/assets.h
+++ b/engines/mtropolis/assets.h
@@ -132,6 +132,7 @@ private:
 	void loadRLEFrames(const Common::Array<uint8> &data);
 	void decompressRLEFrame(size_t frameIndex);
 	void loadUncompressedFrame(const Common::Array<uint8> &data, size_t frameIndex);
+	void decompressQuickTimeFrame(const Common::Array<uint8> &data, size_t frameIndex);
 
 	template<class TSrcNumber, uint32 TSrcLiteralMask, uint32 TSrcTransparentSkipMask, class TDestNumber, uint32 TDestLiteralMask, uint32 TDestTransparentSkipMask>
 	void rleReformat(RleFrame &frame, const Common::Array<TSrcNumber> &srcData, const Graphics::PixelFormat &srcFormatRef, Common::Array<TDestNumber> &destData, const Graphics::PixelFormat &destFormatRef);
diff --git a/engines/mtropolis/data.h b/engines/mtropolis/data.h
index cbe4c8a2887..896d430ec16 100644
--- a/engines/mtropolis/data.h
+++ b/engines/mtropolis/data.h
@@ -1693,6 +1693,11 @@ struct MToonAsset : public DataObject {
 
 	Common::Array<FrameDef> frames;
 
+	// Codec data appears to be a 16-byte header followed by a QuickTime sample description
+	// The 16-byte header is:
+	// uint32be size of codec data
+	// char[4] codec ID
+	// byte[8] unknown (all 0?)
 	Common::Array<uint8> codecData;
 
 	struct FrameRangePart {




More information about the Scummvm-git-logs mailing list