diff options
| -rw-r--r-- | image/codecs/codec.cpp | 2 | ||||
| -rw-r--r-- | image/codecs/truemotion1.cpp | 19 | ||||
| -rw-r--r-- | image/codecs/truemotion1.h | 2 | ||||
| -rw-r--r-- | video/avi_decoder.cpp | 54 | ||||
| -rw-r--r-- | video/avi_decoder.h | 4 | 
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);  | 
