aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--image/codecs/codec.cpp40
-rw-r--r--image/codecs/codec.h5
-rw-r--r--image/pict.cpp36
-rw-r--r--video/qt_decoder.cpp45
4 files changed, 68 insertions, 58 deletions
diff --git a/image/codecs/codec.cpp b/image/codecs/codec.cpp
index 7d4e34320f..530fb3b836 100644
--- a/image/codecs/codec.cpp
+++ b/image/codecs/codec.cpp
@@ -24,13 +24,19 @@
#include "image/codecs/codec.h"
+#include "image/jpeg.h"
#include "image/codecs/bmp_raw.h"
+#include "image/codecs/cdtoons.h"
#include "image/codecs/cinepak.h"
#include "image/codecs/indeo3.h"
#include "image/codecs/mjpeg.h"
#include "image/codecs/mpeg.h"
#include "image/codecs/msvideo1.h"
#include "image/codecs/msrle.h"
+#include "image/codecs/qtrle.h"
+#include "image/codecs/rpza.h"
+#include "image/codecs/smc.h"
+#include "image/codecs/svq1.h"
#include "image/codecs/truemotion1.h"
#include "common/endian.h"
@@ -74,4 +80,38 @@ Codec *createBitmapCodec(uint32 tag, int width, int height, int bitsPerPixel) {
return 0;
}
+Codec *createQuickTimeCodec(uint32 tag, int width, int height, int bitsPerPixel) {
+ switch (tag) {
+ case MKTAG('c','v','i','d'):
+ // Cinepak: As used by most Myst and all Riven videos as well as some Myst ME videos. "The Chief" videos also use this.
+ return new CinepakDecoder(bitsPerPixel);
+ case MKTAG('r','p','z','a'):
+ // Apple Video ("Road Pizza"): Used by some Myst videos.
+ return new RPZADecoder(width, height);
+ case MKTAG('r','l','e',' '):
+ // QuickTime RLE: Used by some Myst ME videos.
+ return new QTRLEDecoder(width, height, bitsPerPixel);
+ case MKTAG('s','m','c',' '):
+ // Apple SMC: Used by some Myst videos.
+ return new SMCDecoder(width, height);
+ case MKTAG('S','V','Q','1'):
+ // Sorenson Video 1: Used by some Myst ME videos.
+ return new SVQ1Decoder(width, height);
+ case MKTAG('S','V','Q','3'):
+ // Sorenson Video 3: Used by some Myst ME videos.
+ warning("Sorenson Video 3 not yet supported");
+ break;
+ case MKTAG('j','p','e','g'):
+ // JPEG: Used by some Myst ME 10th Anniversary videos.
+ return new JPEGDecoder();
+ case MKTAG('Q','k','B','k'):
+ // CDToons: Used by most of the Broderbund games.
+ return new CDToonsDecoder(width, height);
+ default:
+ warning("Unsupported QuickTime codec \'%s\'", tag2str(tag));
+ }
+
+ return 0;
+}
+
} // End of namespace Image
diff --git a/image/codecs/codec.h b/image/codecs/codec.h
index 87d6d6b998..89c8ec9bf5 100644
--- a/image/codecs/codec.h
+++ b/image/codecs/codec.h
@@ -89,6 +89,11 @@ public:
*/
Codec *createBitmapCodec(uint32 tag, int width, int height, int bitsPerPixel);
+/**
+ * Create a codec given a QuickTime compression tag.
+ */
+Codec *createQuickTimeCodec(uint32 tag, int width, int height, int bitsPerPixel);
+
} // End of namespace Image
#endif
diff --git a/image/pict.cpp b/image/pict.cpp
index 07e657f4b2..89f115dc90 100644
--- a/image/pict.cpp
+++ b/image/pict.cpp
@@ -20,8 +20,8 @@
*
*/
-#include "image/jpeg.h"
#include "image/pict.h"
+#include "image/codecs/codec.h"
#include "common/debug.h"
#include "common/endian.h"
@@ -229,7 +229,7 @@ bool PICTDecoder::loadStream(Common::SeekableReadStream &stream) {
// NOTE: This is only a subset of the full PICT format.
// - Only V2 (Extended) Images Supported
- // - CompressedQuickTime (JPEG) compressed data is supported
+ // - CompressedQuickTime compressed data is supported
// - DirectBitsRect/PackBitsRect compressed data is supported
for (uint32 opNum = 0; !stream.eos() && !stream.err() && stream.pos() < stream.size() && _continueParsing; opNum++) {
// PICT v2 opcodes are two bytes
@@ -550,31 +550,37 @@ void PICTDecoder::decodeCompressedQuickTime(Common::SeekableReadStream &stream)
// Now we've reached the image descriptor, so read the relevant data from that
uint32 idStart = stream.pos();
uint32 idSize = stream.readUint32BE();
- uint32 codec = stream.readUint32BE();
- stream.skip(36); // miscellaneous stuff
- uint32 jpegSize = stream.readUint32BE();
+ uint32 codecTag = stream.readUint32BE();
+ stream.skip(24); // miscellaneous stuff
+ uint16 width = stream.readUint16BE();
+ uint16 height = stream.readUint16BE();
+ stream.skip(8); // resolution, dpi
+ uint32 imageSize = stream.readUint32BE();
+ stream.skip(34);
+ uint16 bitsPerPixel = stream.readUint16BE();
stream.skip(idSize - (stream.pos() - idStart)); // more useless stuff
- if (codec != MKTAG('j', 'p', 'e', 'g'))
- error("Unhandled CompressedQuickTime format '%s'", tag2str(codec));
+ Common::SeekableSubReadStream imageStream(&stream, stream.pos(), stream.pos() + imageSize);
- Common::SeekableSubReadStream jpegStream(&stream, stream.pos(), stream.pos() + jpegSize);
+ Codec *codec = createQuickTimeCodec(codecTag, width, height, bitsPerPixel);
+ if (!codec)
+ error("Unhandled CompressedQuickTime format");
- JPEGDecoder jpeg;
- if (!jpeg.loadStream(jpegStream))
- error("PICTDecoder::decodeCompressedQuickTime(): Could not decode JPEG data");
+ const Graphics::Surface *surface = codec->decodeFrame(imageStream);
- const Graphics::Surface *jpegSurface = jpeg.getSurface();
+ if (!surface)
+ error("PICTDecoder::decodeCompressedQuickTime(): Could not decode data");
if (!_outputSurface) {
_outputSurface = new Graphics::Surface();
- _outputSurface->create(_imageRect.width(), _imageRect.height(), jpegSurface->format);
+ _outputSurface->create(_imageRect.width(), _imageRect.height(), surface->format);
}
- for (uint16 y = 0; y < jpegSurface->h; y++)
- memcpy(_outputSurface->getBasePtr(0 + xOffset, y + yOffset), jpegSurface->getBasePtr(0, y), jpegSurface->w * jpegSurface->format.bytesPerPixel);
+ for (uint16 y = 0; y < surface->h; y++)
+ memcpy(_outputSurface->getBasePtr(0 + xOffset, y + yOffset), surface->getBasePtr(0, y), surface->w * surface->format.bytesPerPixel);
stream.seek(startPos + dataSize);
+ delete codec;
}
} // End of namespace Image
diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp
index cd3679615b..0a29692948 100644
--- a/video/qt_decoder.cpp
+++ b/video/qt_decoder.cpp
@@ -39,13 +39,7 @@
#include "common/util.h"
// Video codecs
-#include "image/codecs/cinepak.h"
-#include "image/jpeg.h"
-#include "image/codecs/qtrle.h"
-#include "image/codecs/rpza.h"
-#include "image/codecs/smc.h"
-#include "image/codecs/cdtoons.h"
-#include "image/codecs/svq1.h"
+#include "image/codecs/codec.h"
namespace Video {
@@ -270,42 +264,7 @@ QuickTimeDecoder::VideoSampleDesc::~VideoSampleDesc() {
}
void QuickTimeDecoder::VideoSampleDesc::initCodec() {
- switch (_codecTag) {
- case MKTAG('c','v','i','d'):
- // Cinepak: As used by most Myst and all Riven videos as well as some Myst ME videos. "The Chief" videos also use this.
- _videoCodec = new Image::CinepakDecoder(_bitsPerSample & 0x1f);
- break;
- case MKTAG('r','p','z','a'):
- // Apple Video ("Road Pizza"): Used by some Myst videos.
- _videoCodec = new Image::RPZADecoder(_parentTrack->width, _parentTrack->height);
- break;
- case MKTAG('r','l','e',' '):
- // QuickTime RLE: Used by some Myst ME videos.
- _videoCodec = new Image::QTRLEDecoder(_parentTrack->width, _parentTrack->height, _bitsPerSample & 0x1f);
- break;
- case MKTAG('s','m','c',' '):
- // Apple SMC: Used by some Myst videos.
- _videoCodec = new Image::SMCDecoder(_parentTrack->width, _parentTrack->height);
- break;
- case MKTAG('S','V','Q','1'):
- // Sorenson Video 1: Used by some Myst ME videos.
- _videoCodec = new Image::SVQ1Decoder(_parentTrack->width, _parentTrack->height);
- break;
- case MKTAG('S','V','Q','3'):
- // Sorenson Video 3: Used by some Myst ME videos.
- warning("Sorenson Video 3 not yet supported");
- break;
- case MKTAG('j','p','e','g'):
- // JPEG: Used by some Myst ME 10th Anniversary videos.
- _videoCodec = new Image::JPEGDecoder();
- break;
- case MKTAG('Q','k','B','k'):
- // CDToons: Used by most of the Broderbund games.
- _videoCodec = new Image::CDToonsDecoder(_parentTrack->width, _parentTrack->height);
- break;
- default:
- warning("Unsupported codec \'%s\'", tag2str(_codecTag));
- }
+ _videoCodec = Image::createQuickTimeCodec(_codecTag, _parentTrack->width, _parentTrack->height, _bitsPerSample & 0x1f);
}
QuickTimeDecoder::AudioTrackHandler::AudioTrackHandler(QuickTimeDecoder *decoder, QuickTimeAudioTrack *audioTrack)