aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--image/codecs/codec.cpp2
-rw-r--r--image/codecs/truemotion1.cpp19
-rw-r--r--image/codecs/truemotion1.h2
-rw-r--r--video/avi_decoder.cpp54
-rw-r--r--video/avi_decoder.h4
5 files changed, 72 insertions, 9 deletions
diff --git a/image/codecs/codec.cpp b/image/codecs/codec.cpp
index 64acf3f169..6b0c7ebcfb 100644
--- a/image/codecs/codec.cpp
+++ b/image/codecs/codec.cpp
@@ -61,7 +61,7 @@ Codec *createBitmapCodec(uint32 tag, int width, int height, int bitsPerPixel) {
#ifdef IMAGE_CODECS_TRUEMOTION1_H
case MKTAG('D','U','C','K'):
case MKTAG('d','u','c','k'):
- return new TrueMotion1Decoder(width, height);
+ return new TrueMotion1Decoder();
#endif
#ifdef USE_MPEG2
case MKTAG('m','p','g','2'):
diff --git a/image/codecs/truemotion1.cpp b/image/codecs/truemotion1.cpp
index 741b9d51eb..e60ec6c72e 100644
--- a/image/codecs/truemotion1.cpp
+++ b/image/codecs/truemotion1.cpp
@@ -89,11 +89,8 @@ static const CompressionType compressionTypes[17] = {
{ ALGO_RGB24H, 2, 2, BLOCK_2x2 }
};
-TrueMotion1Decoder::TrueMotion1Decoder(uint16 width, uint16 height) {
- _surface = new Graphics::Surface();
- _surface->create(width, height, getPixelFormat());
- _surface->fillRect(Common::Rect(width, height), getPixelFormat().RGBToColor(0, 0, 0));
-
+TrueMotion1Decoder::TrueMotion1Decoder() {
+ _surface = 0;
_vertPred = 0;
_buf = _mbChangeBits = _indexStream = 0;
@@ -101,8 +98,11 @@ TrueMotion1Decoder::TrueMotion1Decoder(uint16 width, uint16 height) {
}
TrueMotion1Decoder::~TrueMotion1Decoder() {
- _surface->free();
- delete _surface;
+ if (_surface) {
+ _surface->free();
+ delete _surface;
+ }
+
delete[] _vertPred;
}
@@ -194,6 +194,11 @@ void TrueMotion1Decoder::decodeHeader(Common::SeekableReadStream &stream) {
_vertPred = new uint32[_header.xsize];
}
+ if (!_surface) {
+ _surface = new Graphics::Surface();
+ _surface->create(_header.xsize, _header.ysize, getPixelFormat());
+ }
+
// There is 1 change bit per 4 pixels, so each change byte represents
// 32 pixels; divide width by 4 to obtain the number of change bits and
// then round up to the nearest byte.
diff --git a/image/codecs/truemotion1.h b/image/codecs/truemotion1.h
index bbbcd6d6be..51daf607d2 100644
--- a/image/codecs/truemotion1.h
+++ b/image/codecs/truemotion1.h
@@ -39,7 +39,7 @@ namespace Image {
*/
class TrueMotion1Decoder : public Codec {
public:
- TrueMotion1Decoder(uint16 width, uint16 height);
+ TrueMotion1Decoder();
~TrueMotion1Decoder();
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp
index 9b196fefc9..3c1c907097 100644
--- a/video/avi_decoder.cpp
+++ b/video/avi_decoder.cpp
@@ -322,6 +322,9 @@ bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) {
// Seek back to the start of the MOVI list
_fileStream->seek(_movieListStart);
+ // Check if this is a special Duck Truemotion video
+ checkTruemotion1();
+
return true;
}
@@ -658,6 +661,48 @@ void AVIDecoder::forceVideoEnd() {
((AVIVideoTrack *)*it)->forceTrackEnd();
}
+void AVIDecoder::checkTruemotion1() {
+ AVIVideoTrack *track = 0;
+
+ for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++) {
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo) {
+ if (track) {
+ // Multiple tracks; isn't going to be truemotion 1
+ return;
+ }
+
+ track = (AVIVideoTrack *)*it;
+ }
+ }
+
+ // No track found?
+ if (!track)
+ return;
+
+ // Ignore non-truemotion tracks
+ if (!track->isTruemotion1())
+ return;
+
+ // Search for a non-empty frame
+ const Graphics::Surface *frame = 0;
+ for (int i = 0; i < 10 && !frame; i++)
+ frame = decodeNextFrame();
+
+ if (!frame) {
+ // Probably shouldn't happen
+ rewind();
+ return;
+ }
+
+ // Fill in the width/height based on the frame's width/height
+ _header.width = frame->w;
+ _header.height = frame->h;
+ track->forceDimensions(frame->w, frame->h);
+
+ // Rewind us back to the beginning
+ rewind();
+}
+
VideoDecoder::AudioTrack *AVIDecoder::getAudioTrack(int index) {
// AVI audio track indexes are relative to the first track
Track *track = getTrack(index);
@@ -732,6 +777,15 @@ void AVIDecoder::AVIVideoTrack::useInitialPalette() {
}
}
+bool AVIDecoder::AVIVideoTrack::isTruemotion1() const {
+ return _bmInfo.compression == MKTAG('D', 'U', 'C', 'K') || _bmInfo.compression == MKTAG('d', 'u', 'c', 'k');
+}
+
+void AVIDecoder::AVIVideoTrack::forceDimensions(uint16 width, uint16 height) {
+ _bmInfo.width = width;
+ _bmInfo.height = height;
+}
+
bool AVIDecoder::AVIVideoTrack::rewind() {
_curFrame = -1;
diff --git a/video/avi_decoder.h b/video/avi_decoder.h
index 2f7b267d36..28d87bc3b7 100644
--- a/video/avi_decoder.h
+++ b/video/avi_decoder.h
@@ -185,6 +185,9 @@ protected:
void loadPaletteFromChunk(Common::SeekableReadStream *chunk);
void useInitialPalette();
+ bool isTruemotion1() const;
+ void forceDimensions(uint16 width, uint16 height);
+
bool isRewindable() const { return true; }
bool rewind();
@@ -257,6 +260,7 @@ protected:
uint16 getStreamType(uint32 tag) const { return tag & 0xFFFF; }
byte getStreamIndex(uint32 tag) const;
void forceVideoEnd();
+ void checkTruemotion1();
public:
virtual AVIAudioTrack *createAudioTrack(AVIStreamHeader sHeader, PCMWaveFormat wvInfo);