[Scummvm-cvs-logs] SF.net SVN: scummvm:[43833] scummvm/trunk/graphics

mthreepwood at users.sourceforge.net mthreepwood at users.sourceforge.net
Sun Aug 30 21:47:15 CEST 2009


Revision: 43833
          http://scummvm.svn.sourceforge.net/scummvm/?rev=43833&view=rev
Author:   mthreepwood
Date:     2009-08-30 19:47:14 +0000 (Sun, 30 Aug 2009)

Log Message:
-----------
Add an AVI player and MSVideo1 codec for use with some SCI Windows game (such as kq6).

Modified Paths:
--------------
    scummvm/trunk/graphics/module.mk

Added Paths:
-----------
    scummvm/trunk/graphics/video/avi_player.cpp
    scummvm/trunk/graphics/video/avi_player.h
    scummvm/trunk/graphics/video/msvideo1.cpp
    scummvm/trunk/graphics/video/msvideo1.h

Modified: scummvm/trunk/graphics/module.mk
===================================================================
--- scummvm/trunk/graphics/module.mk	2009-08-30 19:33:34 UTC (rev 43832)
+++ scummvm/trunk/graphics/module.mk	2009-08-30 19:47:14 UTC (rev 43833)
@@ -21,9 +21,11 @@
 	thumbnail.o \
 	VectorRenderer.o \
 	VectorRendererSpec.o \
+	video/avi_player.o \
 	video/dxa_decoder.o \
 	video/flic_decoder.o \
 	video/mpeg_player.o \
+	video/msvideo1.o \
 	video/smk_decoder.o \
 	video/video_player.o \
 	video/coktelvideo/indeo3.o \

Added: scummvm/trunk/graphics/video/avi_player.cpp
===================================================================
--- scummvm/trunk/graphics/video/avi_player.cpp	                        (rev 0)
+++ scummvm/trunk/graphics/video/avi_player.cpp	2009-08-30 19:47:14 UTC (rev 43833)
@@ -0,0 +1,383 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/endian.h"
+#include "common/file.h"
+#include "common/stream.h"
+#include "common/events.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+
+#include "graphics/video/avi_player.h"
+
+// Codecs
+#include "graphics/video/msvideo1.h"
+
+namespace Graphics {
+
+AVIPlayer::AVIPlayer(OSystem* syst) : _system(syst) {
+	_videoCodec = NULL;
+	_palette = NULL;
+	_decodedHeader = false;
+	_filesize = 0;
+	_curFrame = 0;
+	_audStream = NULL;
+	_dirtyPalette = false;
+	_stream = NULL;
+	_audHandle = new Audio::SoundHandle();
+	memset(&_wvInfo, 0, sizeof(PCMWAVEFORMAT));
+	memset(&_bmInfo, 0, sizeof(BITMAPINFOHEADER));
+	memset(&_vidsHeader, 0, sizeof(AVIStreamHeader));
+	memset(&_audsHeader, 0, sizeof(AVIStreamHeader));
+	memset(&_ixInfo, 0, sizeof(AVIOLDINDEX));
+}
+
+AVIPlayer::~AVIPlayer() {
+	close();
+	delete _audHandle;
+}
+	
+void AVIPlayer::runHandle(uint32 tag) {
+	assert (_stream);
+	if (_stream->eos())
+		return;
+
+	debug (3, "Decoding tag %s", tag2str(tag));
+		
+	switch (tag) {
+		case ID_RIFF:
+			_filesize = _stream->readUint32LE();
+			assert(_stream->readUint32BE() == ID_AVI);
+			break;
+		case ID_LIST:
+			handleList();
+			break;
+		case ID_AVIH:
+			_header.size = _stream->readUint32LE();
+			_header.microSecondsPerFrame = _stream->readUint32LE();
+			_header.maxBytesPerSecond = _stream->readUint32LE();
+			_header.padding = _stream->readUint32LE();
+			_header.flags = _stream->readUint32LE();
+			_header.totalFrames = _stream->readUint32LE();
+			_header.initialFrames = _stream->readUint32LE();
+			_header.streams = _stream->readUint32LE();
+			_header.bufferSize = _stream->readUint32LE();
+			_header.width = _stream->readUint32LE();
+			_header.height = _stream->readUint32LE();
+			//Ignore 16 bytes of reserved data
+			_stream->skip(16);
+			break;
+		case ID_STRH:
+			handleStreamHeader();
+			break;
+		case ID_STRD: // Extra stream info, safe to ignore
+		case ID_VEDT: // Unknown, safe to ignore
+		case ID_JUNK: // Alignment bytes, should be ignored
+			{
+			uint32 junkSize = _stream->readUint32LE();
+			_stream->skip(junkSize + (junkSize & 1)); // Alignment
+			} break;
+		case ID_IDX1:
+			_ixInfo.size = _stream->readUint32LE();
+			_ixInfo.indices = new AVIOLDINDEX::Index[_ixInfo.size / 16];
+			debug (0, "%d Indices", (_ixInfo.size / 16));
+			for (uint32 i = 0; i < (_ixInfo.size / 16); i++) {
+				_ixInfo.indices[i].id = _stream->readUint32BE();
+				_ixInfo.indices[i].flags = _stream->readUint32LE();
+				_ixInfo.indices[i].offset = _stream->readUint32LE();
+				_ixInfo.indices[i].size = _stream->readUint32LE();
+				debug (0, "Index %d == Tag \'%s\', Offset = %d, Size = %d", i, tag2str(_ixInfo.indices[i].id), _ixInfo.indices[i].offset, _ixInfo.indices[i].size);
+			}
+			break;
+		default: error ("Unknown tag \'%s\' found", tag2str(tag));
+	}
+}
+	
+void AVIPlayer::handleList() {
+	uint32 listSize = _stream->readUint32LE() - 4; // Subtract away listType's 4 bytes
+	uint32 listType = _stream->readUint32BE();
+	uint32 curPos = _stream->pos();
+	
+	debug (0, "Found LIST of type %s", tag2str(listType));
+	
+	while ((_stream->pos() - curPos) < listSize)
+		runHandle(_stream->readUint32BE());
+	
+	// We now have all the header data
+	if (listType == ID_HDRL)
+		_decodedHeader = true;
+}
+	
+void AVIPlayer::handleStreamHeader() {
+	AVIStreamHeader sHeader;	
+	sHeader.size = _stream->readUint32LE();
+	sHeader.streamType = _stream->readUint32BE();
+	if (sHeader.streamType == ID_MIDS || sHeader.streamType == ID_TXTS)
+		error ("Unhandled MIDI/Text stream");
+	sHeader.streamHandler = _stream->readUint32BE();
+	sHeader.flags = _stream->readUint32LE();
+	sHeader.priority = _stream->readUint16LE();
+	sHeader.language = _stream->readUint16LE();
+	sHeader.initialFrames = _stream->readUint32LE();
+	sHeader.scale = _stream->readUint32LE();
+	sHeader.rate = _stream->readUint32LE();
+	sHeader.start = _stream->readUint32LE();
+	sHeader.length = _stream->readUint32LE();
+	sHeader.bufferSize = _stream->readUint32LE();
+	sHeader.quality = _stream->readUint32LE();
+	sHeader.sampleSize = _stream->readUint32LE();
+	sHeader.frame.left = _stream->readSint16LE();
+	sHeader.frame.top = _stream->readSint16LE();
+	sHeader.frame.right = _stream->readSint16LE();
+	sHeader.frame.bottom = _stream->readSint16LE();
+		
+	assert (_stream->readUint32BE() == ID_STRF);
+	/* uint32 strfSize = */ _stream->readUint32LE();
+	
+	if (sHeader.streamType == ID_VIDS) {
+		_vidsHeader = sHeader;
+		
+		_bmInfo.size = _stream->readUint32LE();
+		_bmInfo.width = _stream->readUint32LE();
+		assert (_header.width == _bmInfo.width);
+		_bmInfo.height = _stream->readUint32LE();
+		assert (_header.height == _bmInfo.height);	
+		_bmInfo.planes = _stream->readUint16LE();
+		_bmInfo.bitCount = _stream->readUint16LE();
+		_bmInfo.compression = _stream->readUint32BE();
+		_bmInfo.sizeImage = _stream->readUint32LE();
+		_bmInfo.xPelsPerMeter = _stream->readUint32LE();
+		_bmInfo.yPelsPerMeter = _stream->readUint32LE();
+		_bmInfo.clrUsed = _stream->readUint32LE();
+		_bmInfo.clrImportant = _stream->readUint32LE();
+		
+		if (_bmInfo.bitCount == 8) {
+			if (_bmInfo.clrUsed == 0)
+				_bmInfo.clrUsed = 256;
+			
+			_palette = (byte *)malloc(256 * 4);
+			
+			for (uint32 i = 0; i < _bmInfo.clrUsed; i++) {
+				_palette[i * 4 + 2] = _stream->readByte();
+				_palette[i * 4 + 1] = _stream->readByte();
+				_palette[i * 4] = _stream->readByte();
+				_palette[i * 4 + 3] = _stream->readByte();
+			}
+			
+			// Assign the palette to be dirty
+			_dirtyPalette = true;
+		}
+	} else if (sHeader.streamType == ID_AUDS) {
+		_audsHeader = sHeader;
+		
+		_wvInfo.tag = _stream->readUint16LE();
+		_wvInfo.channels = _stream->readUint16LE();
+		_wvInfo.samplesPerSec = _stream->readUint32LE();
+		_wvInfo.avgBytesPerSec = _stream->readUint32LE();
+		_wvInfo.blockAlign = _stream->readUint16LE();
+		_wvInfo.size = _stream->readUint16LE();
+	}
+}
+
+bool AVIPlayer::open(Common::String filename) {
+	Common::File *file = new Common::File();
+
+	if (!file->open(filename.c_str()))
+		return false;
+		
+	open(file);
+	
+	return true;
+}
+
+void AVIPlayer::open(Common::SeekableReadStream *stream) {
+	close();
+
+	assert(stream);
+	_stream = stream;
+	
+	_decodedHeader = false;
+	_curFrame = 0;
+	
+	// Read chunks until we have decoded the header
+	while (!_decodedHeader)
+		runHandle(_stream->readUint32BE());
+
+	uint32 nextTag = _stream->readUint32BE();
+	
+	// Throw out any JUNK section
+	if (nextTag == ID_JUNK) {
+		runHandle(ID_JUNK);
+		nextTag = _stream->readUint32BE();
+	}
+	
+	// Ignore the 'movi' LIST
+	if (nextTag == ID_LIST) {
+		_stream->readUint32BE(); // Skip size
+		if (_stream->readUint32BE() != ID_MOVI)
+			error ("Expected 'movi' LIST");
+	} else
+		error ("Expected 'movi' LIST");
+		
+	// Now, create the codec
+	_videoCodec = createCodec();
+	
+	// Initialize the video stuff too
+	_audStream = createAudioStream();
+	if (_audStream)
+		_system->getMixer()->playInputStream(Audio::Mixer::kPlainSoundType, _audHandle, _audStream);
+			
+	debug (0, "Frames = %d, Dimensions = %d x %d", _header.totalFrames, _header.width, _header.height);
+	debug (0, "Frame Rate = %d", getFrameRate());
+	if (_header.flags & AVIF_ISINTERLEAVED)
+		debug (0, "Sound Rate = %d", AUDIO_RATE);
+	debug (0, "Video Codec = \'%s\'", tag2str(_vidsHeader.streamHandler));
+}
+
+void AVIPlayer::close() {
+	delete _stream;
+		
+	// Deinitialize sound
+	_system->getMixer()->stopHandle(*_audHandle);
+		
+	if (_palette) {
+		free(_palette);
+		_palette = NULL;
+	}
+	
+	_decodedHeader = false;
+	_filesize = 0;
+	
+	delete _videoCodec;
+	delete[] _ixInfo.indices;
+}
+	
+Surface *AVIPlayer::getNextFrame() {
+	uint32 nextTag = _stream->readUint32BE();
+		
+	if (nextTag == ID_LIST) {
+		// A list of audio/video chunks
+		uint32 listSize = _stream->readUint32LE() - 4;
+		int32 startPos = _stream->pos();
+
+		if (_stream->readUint32BE() != ID_REC)
+			error ("Expected 'rec ' LIST");
+		
+		// Decode chunks in the list and see if we get a frame
+		Surface *frame = NULL;
+		while (_stream->pos() < startPos + (int32)listSize) {
+			Surface *temp = getNextFrame();
+			if (temp)
+				frame = temp;
+		}
+
+		return frame;
+	} else if (getStreamType(nextTag) == 'wb') {
+		// Audio Chunk
+		uint32 chunkSize = _stream->readUint32LE();
+		byte *data = new byte[chunkSize];
+		_stream->read(data, chunkSize);
+		_audStream->queueBuffer(data, chunkSize);
+		_stream->skip(chunkSize & 1); // Alignment
+	} else if (getStreamType(nextTag) == 'dc' || getStreamType(nextTag) == 'id') {
+		// Compressed Frame
+		_curFrame++;
+		uint32 chunkSize = _stream->readUint32LE();
+
+		if (chunkSize == 0) // Keep last frame on screen
+			return NULL;
+		
+		Common::SeekableReadStream *frameData = _stream->readStream(chunkSize);
+		Graphics::Surface *surface = _videoCodec->decodeImage(frameData);
+		delete frameData;
+		_stream->skip(chunkSize & 1); // Alignment
+		return surface;
+	} else if (getStreamType(nextTag) == 'pc') {
+		// Palette Change
+		_stream->readUint32LE(); // Chunk size, not needed here
+		byte firstEntry = _stream->readByte();
+		uint16 numEntries = _stream->readByte();
+		_stream->readUint16LE(); // Reserved
+		
+		// 0 entries means all colors are going to be changed
+		if (numEntries == 0)
+			numEntries = 256;
+			
+		for (uint16 i = firstEntry; i < numEntries + firstEntry; i++) {
+			_palette[i * 4] = _stream->readByte();
+			_palette[i * 4 + 1] = _stream->readByte();
+			_palette[i * 4 + 2] = _stream->readByte();
+			_stream->readByte(); // Flags that don't serve us any purpose
+		}
+		
+		// Mark the palette as dirty
+		_dirtyPalette = true;
+
+		// No alignment necessary. It's always even.
+	} else if (nextTag == ID_JUNK) {
+		runHandle(ID_JUNK);
+	} else
+		error ("Tag = \'%s\'", tag2str(nextTag));
+
+	return NULL;
+}
+
+Codec *AVIPlayer::createCodec() {
+	switch (_vidsHeader.streamHandler) {
+		case ID_CRAM:
+		case ID_MSVC:
+		case ID_WHAM:
+			return new MSVideo1Decoder(_bmInfo.width, _bmInfo.height, _bmInfo.bitCount);
+		default:
+			warning ("Unknown/Unhandled compression format \'%s\'", tag2str(_vidsHeader.streamHandler));
+	}
+	
+	return NULL;
+}
+
+Audio::AppendableAudioStream *AVIPlayer::createAudioStream() {
+	if (_wvInfo.tag == WAVE_FORMAT_PCM)
+		return Audio::makeAppendableAudioStream(AUDIO_RATE, Audio::Mixer::FLAG_UNSIGNED|Audio::Mixer::FLAG_AUTOFREE);
+	
+	if (_wvInfo.tag != 0) // No sound
+		warning ("Unsupported AVI audio format %d", _wvInfo.tag);
+
+	return NULL;
+}
+	
+byte AVIPlayer::char2num(char c) {
+	return (c >= 48 && c <= 57) ? c - 48 : 0;
+}
+	
+byte AVIPlayer::getStreamNum(uint32 tag) {
+	return char2num((char)(tag >> 24)) * 16 + char2num((char)(tag >> 16));
+}
+
+uint16 AVIPlayer::getStreamType(uint32 tag) {
+	return tag & 0xffff;
+}
+
+} // End of namespace JMP


Property changes on: scummvm/trunk/graphics/video/avi_player.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/graphics/video/avi_player.h
===================================================================
--- scummvm/trunk/graphics/video/avi_player.h	                        (rev 0)
+++ scummvm/trunk/graphics/video/avi_player.h	2009-08-30 19:47:14 UTC (rev 43833)
@@ -0,0 +1,241 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef GRAPHICS_AVI_PLAYER_H
+#define GRAPHICS_AVI_PLAYER_H
+
+#include "common/file.h"
+#include "common/system.h"
+#include "common/rect.h"
+#include "common/util.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+
+namespace Graphics {
+	
+#define UNKNOWN_HEADER(a) error("Unknown header found -- \'%s\'", tag2str(a))
+#define AUDIO_RATE (_audsHeader.rate / _audsHeader.scale)
+	
+// ID's That are used throughout the AVI files
+// that will be handled by this player
+#define ID_RIFF MKID_BE('RIFF')
+#define ID_AVI  MKID_BE('AVI ')
+#define ID_LIST MKID_BE('LIST')
+#define ID_HDRL MKID_BE('hdrl')
+#define ID_AVIH MKID_BE('avih')
+#define ID_STRL MKID_BE('strl')
+#define ID_STRH MKID_BE('strh')
+#define ID_VIDS MKID_BE('vids')
+#define ID_AUDS MKID_BE('auds')
+#define ID_MIDS MKID_BE('mids')
+#define ID_TXTS MKID_BE('txts')
+#define ID_JUNK MKID_BE('JUNK')
+#define ID_STRF MKID_BE('strf')
+#define ID_MOVI MKID_BE('movi')
+#define ID_REC  MKID_BE('rec ')
+#define ID_VEDT MKID_BE('vedt')
+#define ID_IDX1 MKID_BE('idx1')
+#define ID_STRD MKID_BE('strd')
+//#define ID_INFO MKID_BE('INFO')
+
+// Codec tags
+#define ID_RLE  MKID_BE('RLE ')
+#define ID_CRAM MKID_BE('CRAM')
+#define ID_MSVC MKID_BE('msvc')
+#define ID_WHAM MKID_BE('WHAM')
+#define ID_CVID MKID_BE('cvid')
+#define ID_IV32 MKID_BE('iv32')
+
+struct BITMAPINFOHEADER {
+	uint32 size;
+	uint32 width;
+	uint32 height;
+	uint16 planes;
+	uint16 bitCount;
+	uint32 compression;
+	uint32 sizeImage;
+	uint32 xPelsPerMeter;
+	uint32 yPelsPerMeter;
+	uint32 clrUsed;
+	uint32 clrImportant;
+};
+
+struct WAVEFORMAT {
+	uint16 tag;
+	uint16 channels;
+	uint32 samplesPerSec;
+	uint32 avgBytesPerSec;
+	uint16 blockAlign;
+};
+
+struct PCMWAVEFORMAT : public WAVEFORMAT {
+	uint16 size;
+};
+
+struct WAVEFORMATEX : public WAVEFORMAT {
+	uint16 bitsPerSample;
+	uint16 size;
+};
+
+struct AVIOLDINDEX {
+	uint32 size;
+	struct Index {
+		uint32 id;
+		uint32 flags;
+		uint32 offset;
+		uint32 size;
+	} *indices;
+};
+	
+// Index Flags
+enum {
+	AVIIF_INDEX = 0x10
+};
+
+enum {
+	WAVE_INVALIDFORMAT = 0,
+	WAVE_FORMAT_PCM = 1,
+	WAVE_FORMAT_1M08 = 1,
+	WAVE_FORMAT_1S08 = 2,
+	WAVE_FORMAT_1M16 = 4,
+	WAVE_FORMAT_1S16 = 8,
+	WAVE_FORMAT_2M08 = 16,
+	WAVE_FORMAT_2S08 = 32,
+	WAVE_FORMAT_2M16 = 64,
+	WAVE_FORMAT_2S16 = 128,
+	WAVE_FORMAT_4M08 = 256,
+	WAVE_FORMAT_4S08 = 512,
+	WAVE_FORMAT_4M16 = 1024,
+	WAVE_FORMAT_4S16 = 2048
+};
+
+struct AVIHeader {
+	uint32 size;
+	uint32 microSecondsPerFrame;
+	uint32 maxBytesPerSecond;
+	uint32 padding;
+	uint32 flags;
+	uint32 totalFrames;
+	uint32 initialFrames;
+	uint32 streams;
+	uint32 bufferSize;
+	uint32 width;
+	uint32 height;
+};
+	
+// Flags from the AVIHeader
+enum {
+	AVIF_HASINDEX = 0x00000010,
+	AVIF_MUSTUSEINDEX = 0x00000020,
+	AVIF_ISINTERLEAVED = 0x00000100,
+	AVIF_TRUSTCKTYPE = 0x00000800,
+	AVIF_WASCAPTUREFILE = 0x00010000,
+	AVIF_WASCOPYRIGHTED = 0x00020000
+};
+	
+struct AVIStreamHeader {
+	uint32 size;
+	uint32 streamType;
+	uint32 streamHandler;
+	uint32 flags;
+	uint16 priority;
+	uint16 language;
+	uint32 initialFrames;
+	uint32 scale;
+	uint32 rate;
+	uint32 start;
+	uint32 length;
+	uint32 bufferSize;
+	uint32 quality;
+	uint32 sampleSize;
+	Common::Rect frame;
+};
+	
+class Codec {
+public:
+	Codec() {}
+	virtual ~Codec() {}
+	virtual Graphics::Surface *decodeImage(Common::SeekableReadStream *stream) = 0;
+};
+
+class AVIPlayer {
+public:	
+	AVIPlayer(OSystem* syst);
+	~AVIPlayer();
+	
+	// Open/Load an AVI video from "filename"
+	bool open(Common::String filename);
+	
+	// Open/Load an AVI video from a stream
+	void open(Common::SeekableReadStream *stream);
+	
+	// Close the current AVI video and release any data
+	void close();
+	
+	uint32 getFrameRate() { return _vidsHeader.rate / _vidsHeader.scale; }
+	byte *getPalette() { return _palette; _dirtyPalette = false; }
+	Surface *getNextFrame();
+	bool dirtyPalette() { return _dirtyPalette; }
+	uint32 getCurFrame() { return _curFrame; }
+	uint32 getFrameCount() { return _header.totalFrames; }
+private:
+	OSystem *_system;
+	Common::SeekableReadStream *_stream;
+	BITMAPINFOHEADER _bmInfo;
+	PCMWAVEFORMAT _wvInfo;
+	AVIOLDINDEX _ixInfo;
+	AVIHeader _header;
+	AVIStreamHeader _vidsHeader;
+	AVIStreamHeader _audsHeader;
+	byte *_palette;
+	
+	bool _decodedHeader;
+	uint32 _curFrame;
+	bool _dirtyPalette;
+	
+	Codec *_videoCodec;
+	Codec *createCodec();
+	
+	void runHandle(uint32 tag);
+	void handleList();
+	void handleStreamHeader();
+	void handlePalChange();
+	
+	Audio::SoundHandle *_audHandle;
+	Audio::AppendableAudioStream *_audStream;
+	Audio::AppendableAudioStream *createAudioStream();
+
+	uint32 _filesize;
+	
+	// Helper functions
+	static byte char2num(char c);
+	static byte getStreamNum(uint32 tag);
+	static uint16 getStreamType(uint32 tag);
+};
+
+} // End of namespace JMP
+
+#endif


Property changes on: scummvm/trunk/graphics/video/avi_player.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/graphics/video/msvideo1.cpp
===================================================================
--- scummvm/trunk/graphics/video/msvideo1.cpp	                        (rev 0)
+++ scummvm/trunk/graphics/video/msvideo1.cpp	2009-08-30 19:47:14 UTC (rev 43833)
@@ -0,0 +1,139 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+ 
+ // Based off ffmpeg's msvideo.cpp
+ 
+#include "graphics/video/msvideo1.h"
+
+namespace Graphics {
+
+#define CHECK_STREAM_PTR(n) \
+  if ((stream->pos() + n) > stream->size() ) { \
+	warning ("MS Video-1: Stream out of bounds (%d >= %d)", stream->pos() + n, stream->size()); \
+    return; \
+  }
+  
+MSVideo1Decoder::MSVideo1Decoder(uint16 width, uint16 height, byte bitsPerPixel) : Codec() {
+	_surface = new Graphics::Surface();
+	_surface->create(width, height, (bitsPerPixel == 8) ? 1 : 2);
+	_bitsPerPixel = bitsPerPixel;
+}
+
+MSVideo1Decoder::~MSVideo1Decoder() {
+	_surface->free();
+	delete _surface;
+}
+
+void MSVideo1Decoder::decode8(Common::SeekableReadStream *stream) {
+    byte colors[8];
+    byte *pixels = (byte *)_surface->pixels;
+    uint16 stride = _surface->w;
+
+    int skipBlocks = 0;
+    uint16 blocks_wide = _surface->w / 4;
+    uint16 blocks_high = _surface->h / 4;
+    uint32 totalBlocks = blocks_wide * blocks_high;
+    uint32 blockInc = 4;
+    uint16 rowDec = stride + 4;
+
+    for (uint16 block_y = blocks_high; block_y > 0; block_y--) {
+        uint32 blockPtr = (block_y * 4 - 1) * stride;
+        for (uint16 block_x = blocks_wide; block_x > 0; block_x--) {
+            // check if this block should be skipped
+            if (skipBlocks > 0) {
+                blockPtr += blockInc;
+                skipBlocks--;
+                totalBlocks--;
+                continue;
+            }
+
+            uint32 pixelPtr = blockPtr;
+
+            /* get the next two bytes in the encoded data stream */
+            CHECK_STREAM_PTR(2);
+            byte byte_a = stream->readByte();
+            byte byte_b = stream->readByte();
+
+            /* check if the decode is finished */
+            if (byte_a == 0 && byte_b == 0 && totalBlocks == 0) {
+                return;
+            } else if ((byte_b & 0xFC) == 0x84) {
+                // skip code, but don't count the current block
+                skipBlocks = ((byte_b - 0x84) << 8) + byte_a - 1;
+            } else if (byte_b < 0x80) {
+                // 2-color encoding
+                uint16 flags = (byte_b << 8) | byte_a;
+
+                CHECK_STREAM_PTR(2);
+                colors[0] = stream->readByte();
+                colors[1] = stream->readByte();
+
+                for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
+                    for (byte pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
+                        pixels[pixelPtr++] = colors[(flags & 0x1) ^ 1];
+                    pixelPtr -= rowDec;
+                }
+            } else if (byte_b >= 0x90) {
+                // 8-color encoding
+                uint16 flags = (byte_b << 8) | byte_a;
+
+                CHECK_STREAM_PTR(8);
+				for (byte i = 0; i < 8; i++)
+					colors[i] = stream->readByte();
+
+                for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
+                    for (byte pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
+                        pixels[pixelPtr++] = colors[((pixel_y & 0x2) << 1) + (pixel_x & 0x2) + ((flags & 0x1) ^ 1)];
+                    pixelPtr -= rowDec;
+                }
+            } else {
+                // 1-color encoding
+                colors[0] = byte_a;
+
+                for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
+                    for (byte pixel_x = 0; pixel_x < 4; pixel_x++)
+                        pixels[pixelPtr++] = colors[0];
+                    pixelPtr -= rowDec;
+                }
+            }
+
+            blockPtr += blockInc;
+            totalBlocks--;
+        }
+    }
+}
+
+Graphics::Surface *MSVideo1Decoder::decodeImage(Common::SeekableReadStream *stream) {
+	if (_bitsPerPixel == 8)
+		decode8(stream);
+	else {
+    //	decode16(stream);
+		error ("Unhandled MS Video-1 16bpp encoding");
+	}
+
+    return _surface;
+}
+
+} // End of namespace JMP


Property changes on: scummvm/trunk/graphics/video/msvideo1.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/graphics/video/msvideo1.h
===================================================================
--- scummvm/trunk/graphics/video/msvideo1.h	                        (rev 0)
+++ scummvm/trunk/graphics/video/msvideo1.h	2009-08-30 19:47:14 UTC (rev 43833)
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+ 
+#ifndef GRAPHICS_MSVIDEO1_H
+#define GRAPHICS_MSVIDEO1_H
+ 
+#include "graphics/video/avi_player.h"
+#include "graphics/surface.h"
+ 
+namespace Graphics {
+ 
+class MSVideo1Decoder : public Codec {
+public:
+	MSVideo1Decoder(uint16 width, uint16 height, byte bitsPerPixel);
+	~MSVideo1Decoder();
+
+	Surface *decodeImage(Common::SeekableReadStream *stream);
+
+private:
+	byte _bitsPerPixel;
+	
+	Surface *_surface;
+	
+	void decode8(Common::SeekableReadStream *stream);
+	//void decode16(Common::SeekableReadStream *stream);
+};
+
+}
+
+#endif


Property changes on: scummvm/trunk/graphics/video/msvideo1.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list