[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