diff options
author | Matthew Hoops | 2014-02-27 21:27:25 -0500 |
---|---|---|
committer | Matthew Hoops | 2014-02-28 00:32:06 -0500 |
commit | acec700c11040320122ed86cd5f1dad20de2d2a8 (patch) | |
tree | 501426eba2b1b2c8aa66748d8152db6e703d94d0 | |
parent | 05e9ff136ae059622a0262380be7bc6460d204f0 (diff) | |
download | scummvm-rg350-acec700c11040320122ed86cd5f1dad20de2d2a8.tar.gz scummvm-rg350-acec700c11040320122ed86cd5f1dad20de2d2a8.tar.bz2 scummvm-rg350-acec700c11040320122ed86cd5f1dad20de2d2a8.zip |
IMAGE: Share the same pool of codecs between PICT and QuickTime
-rw-r--r-- | image/codecs/codec.cpp | 40 | ||||
-rw-r--r-- | image/codecs/codec.h | 5 | ||||
-rw-r--r-- | image/pict.cpp | 36 | ||||
-rw-r--r-- | video/qt_decoder.cpp | 45 |
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) |