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

mthreepwood at users.sourceforge.net mthreepwood at users.sourceforge.net
Sun May 23 20:33:55 CEST 2010


Revision: 49165
          http://scummvm.svn.sourceforge.net/scummvm/?rev=49165&view=rev
Author:   mthreepwood
Date:     2010-05-23 18:33:55 +0000 (Sun, 23 May 2010)

Log Message:
-----------
Move Mohawk's QuickTime code to graphics/ (and QDM2 to sound, disabled when Mohawk is not enabled) so SCI can use the code.

Modified Paths:
--------------
    scummvm/trunk/engines/mohawk/console.cpp
    scummvm/trunk/engines/mohawk/graphics.cpp
    scummvm/trunk/engines/mohawk/graphics.h
    scummvm/trunk/engines/mohawk/module.mk
    scummvm/trunk/engines/mohawk/mohawk.cpp
    scummvm/trunk/engines/mohawk/myst.cpp
    scummvm/trunk/engines/mohawk/myst_pict.cpp
    scummvm/trunk/engines/mohawk/myst_pict.h
    scummvm/trunk/engines/mohawk/myst_scripts.cpp
    scummvm/trunk/engines/mohawk/riven.cpp
    scummvm/trunk/engines/mohawk/riven_external.cpp
    scummvm/trunk/engines/mohawk/riven_scripts.cpp
    scummvm/trunk/graphics/conversion.h
    scummvm/trunk/graphics/module.mk
    scummvm/trunk/graphics/video/avi_decoder.cpp
    scummvm/trunk/sound/module.mk

Added Paths:
-----------
    scummvm/trunk/engines/mohawk/video.cpp
    scummvm/trunk/engines/mohawk/video.h
    scummvm/trunk/graphics/video/codecs/cinepak.cpp
    scummvm/trunk/graphics/video/codecs/cinepak.h
    scummvm/trunk/graphics/video/codecs/mjpeg.cpp
    scummvm/trunk/graphics/video/codecs/mjpeg.h
    scummvm/trunk/graphics/video/codecs/qtrle.cpp
    scummvm/trunk/graphics/video/codecs/qtrle.h
    scummvm/trunk/graphics/video/codecs/rpza.cpp
    scummvm/trunk/graphics/video/codecs/rpza.h
    scummvm/trunk/graphics/video/codecs/smc.cpp
    scummvm/trunk/graphics/video/codecs/smc.h
    scummvm/trunk/graphics/video/qt_decoder.cpp
    scummvm/trunk/graphics/video/qt_decoder.h
    scummvm/trunk/sound/decoders/qdm2.cpp
    scummvm/trunk/sound/decoders/qdm2.h
    scummvm/trunk/sound/decoders/qdm2data.h

Removed Paths:
-------------
    scummvm/trunk/engines/mohawk/jpeg.cpp
    scummvm/trunk/engines/mohawk/jpeg.h
    scummvm/trunk/engines/mohawk/video/

Modified: scummvm/trunk/engines/mohawk/console.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/console.cpp	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/engines/mohawk/console.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -30,7 +30,7 @@
 #include "mohawk/riven.h"
 #include "mohawk/livingbooks.h"
 #include "mohawk/sound.h"
-#include "mohawk/video/video.h"
+#include "mohawk/video.h"
 
 namespace Mohawk {
 

Modified: scummvm/trunk/engines/mohawk/graphics.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/graphics.cpp	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/engines/mohawk/graphics.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -78,8 +78,7 @@
 		error("Myst requires greater than 256 colors to run");
 
 	if (_vm->getFeatures() & GF_ME) {
-		// We want to delete our own JPEG surfaces, so don't free after use.
-		_jpegDecoder = new JPEGDecoder(false);
+		_jpegDecoder = new Graphics::JPEGDecoder();
 		_pictDecoder = new MystPICT(_jpegDecoder);
 	} else {
 		_jpegDecoder = NULL;
@@ -152,9 +151,10 @@
 	if (_vm->getFeatures() & GF_ME && _vm->getPlatform() == Common::kPlatformMacintosh && _pictureFile.picFile.isOpen()) {
 		for (uint32 i = 0; i < _pictureFile.pictureCount; i++)
 			if (_pictureFile.entries[i].id == image) {
-				if (_pictureFile.entries[i].type == 0)
-					surface = _jpegDecoder->decodeImage(new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size));
-				else if (_pictureFile.entries[i].type == 1)
+				if (_pictureFile.entries[i].type == 0) {
+					Graphics::Surface *jpegSurface = _jpegDecoder->decodeImage(new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size));
+					surface->copyFrom(*jpegSurface);
+				} else if (_pictureFile.entries[i].type == 1)
 					surface = _pictDecoder->decodeImage(new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size));
 				else
 					error ("Unknown Picture File type %d", _pictureFile.entries[i].type);

Modified: scummvm/trunk/engines/mohawk/graphics.h
===================================================================
--- scummvm/trunk/engines/mohawk/graphics.h	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/engines/mohawk/graphics.h	2010-05-23 18:33:55 UTC (rev 49165)
@@ -27,11 +27,11 @@
 #define MOHAWK_GRAPHICS_H
 
 #include "mohawk/bitmap.h"
-#include "mohawk/jpeg.h"
 #include "mohawk/livingbooks.h"
 #include "mohawk/myst_pict.h"
 
 #include "common/file.h"
+#include "graphics/video/codecs/mjpeg.h"
 
 namespace Mohawk {
 
@@ -96,8 +96,8 @@
 	void loadExternalPictureFile(uint16 stack);
 	void copyImageSectionToScreen(uint16 image, Common::Rect src, Common::Rect dest);
 	void copyImageToScreen(uint16 image, Common::Rect dest);
-	void showCursor(void);
-	void hideCursor(void);
+	void showCursor();
+	void hideCursor();
 	void changeCursor(uint16);
 
 	void drawRect(Common::Rect rect, bool active);
@@ -105,7 +105,7 @@
 	MohawkEngine_Myst *_vm;
 	MystBitmap *_bmpDecoder;
 	MystPICT *_pictDecoder;
-	JPEGDecoder *_jpegDecoder;
+	Graphics::JPEGDecoder *_jpegDecoder;
 	Graphics::PixelFormat _pixelFormat;
 
 	struct PictureFile {

Deleted: scummvm/trunk/engines/mohawk/jpeg.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/jpeg.cpp	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/engines/mohawk/jpeg.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -1,87 +0,0 @@
-/* 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/system.h"
-#include "graphics/conversion.h" // For YUV2RGB
-
-#include "mohawk/jpeg.h"
-
-namespace Mohawk {
-
-JPEGDecoder::JPEGDecoder(bool freeSurfaceAfterUse) : Graphics::Codec(), _freeSurfaceAfterUse(freeSurfaceAfterUse) {
-	_jpeg = new Graphics::JPEG();
-	_pixelFormat = g_system->getScreenFormat();
-	_surface = NULL;
-}
-
-JPEGDecoder::~JPEGDecoder() {
-	delete _jpeg;
-
-	if (_surface) {
-		_surface->free();
-		delete _surface;
-	}
-}
-
-Graphics::Surface *JPEGDecoder::decodeImage(Common::SeekableReadStream* stream) {
-	_jpeg->read(stream);
-	Graphics::Surface *ySurface = _jpeg->getComponent(1);
-	Graphics::Surface *uSurface = _jpeg->getComponent(2);
-	Graphics::Surface *vSurface = _jpeg->getComponent(3);
-
-	Graphics::Surface *destSurface = NULL;
-
-	// If we should free the surface after use, use the internal _surface storage
-	// (this should be used when using as a Codec, as the Codecs should free their
-	// surfaces when deleting the Codec object). Otherwise, create a new Surface
-	// as the destination.
-	if (_freeSurfaceAfterUse) {
-		if (!_surface) {
-			_surface = new Graphics::Surface();
-			_surface->create(ySurface->w, ySurface->h, _pixelFormat.bytesPerPixel);
-		}
-		destSurface = _surface;
-	} else {
-		destSurface = new Graphics::Surface();
-		destSurface->create(ySurface->w, ySurface->h, _pixelFormat.bytesPerPixel);
-	}
-
-	assert(destSurface);
-
-	for (uint16 i = 0; i < destSurface->h; i++) {
-		for (uint16 j = 0; j < destSurface->w; j++) {
-			byte r = 0, g = 0, b = 0;
-			Graphics::YUV2RGB(*((byte *)ySurface->getBasePtr(j, i)), *((byte *)uSurface->getBasePtr(j, i)), *((byte *)vSurface->getBasePtr(j, i)), r, g, b);
-			if (_pixelFormat.bytesPerPixel == 2)
-				*((uint16 *)destSurface->getBasePtr(j, i)) = _pixelFormat.RGBToColor(r, g, b);
-			else
-				*((uint32 *)destSurface->getBasePtr(j, i)) = _pixelFormat.RGBToColor(r, g, b);
-		}
-	}
-
-	return destSurface;
-}
-
-} // End of namespace Mohawk

Deleted: scummvm/trunk/engines/mohawk/jpeg.h
===================================================================
--- scummvm/trunk/engines/mohawk/jpeg.h	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/engines/mohawk/jpeg.h	2010-05-23 18:33:55 UTC (rev 49165)
@@ -1,59 +0,0 @@
-/* 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 MOHAWK_JPEG_H
-#define MOHAWK_JPEG_H
-
-#include "common/scummsys.h"
-#include "common/stream.h"
-
-#include "graphics/video/codecs/codec.h"
-#include "graphics/jpeg.h"
-#include "graphics/pixelformat.h"
-
-namespace Mohawk {
-
-// Mohawk's JPEG Decoder
-// Basically a wrapper around JPEG which converts to RGB and also functions
-// as a Codec.
-
-class JPEGDecoder : public Graphics::Codec {
-public:
-	JPEGDecoder(bool freeSurfaceAfterUse);
-	~JPEGDecoder();
-
-	Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
-	Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
-
-private:
-	Graphics::PixelFormat _pixelFormat;
-	Graphics::JPEG *_jpeg;
-	Graphics::Surface *_surface;
-	bool _freeSurfaceAfterUse;
-};
-
-} // End of namespace Mohawk
-
-#endif

Modified: scummvm/trunk/engines/mohawk/module.mk
===================================================================
--- scummvm/trunk/engines/mohawk/module.mk	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/engines/mohawk/module.mk	2010-05-23 18:33:55 UTC (rev 49165)
@@ -6,7 +6,6 @@
 	detection.o \
 	dialogs.o \
 	graphics.o \
-	jpeg.o \
 	livingbooks.o \
 	mohawk.o \
 	myst.o \
@@ -22,13 +21,7 @@
 	riven_scripts.o \
 	riven_vars.o \
 	sound.o \
-	video/cinepak.o \
-	video/qdm2.o \
-	video/qtrle.o \
-	video/qt_player.o \
-	video/rpza.o \
-	video/smc.o \
-	video/video.o
+	video.o
 
 
 # This module can be built as a plugin

Modified: scummvm/trunk/engines/mohawk/mohawk.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/mohawk.cpp	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/engines/mohawk/mohawk.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -35,7 +35,7 @@
 #include "mohawk/mohawk.h"
 #include "mohawk/dialogs.h"
 #include "mohawk/sound.h"
-#include "mohawk/video/video.h"
+#include "mohawk/video.h"
 
 #include "sound/mixer.h"
 

Modified: scummvm/trunk/engines/mohawk/myst.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/myst.cpp	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/engines/mohawk/myst.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -33,7 +33,7 @@
 #include "mohawk/dialogs.h"
 #include "mohawk/resource.h"
 #include "mohawk/resource_cache.h"
-#include "mohawk/video/video.h"
+#include "mohawk/video.h"
 
 namespace Mohawk {
 

Modified: scummvm/trunk/engines/mohawk/myst_pict.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/myst_pict.cpp	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/engines/mohawk/myst_pict.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -32,7 +32,7 @@
 // The PICT code is based off of the QuickDraw specs:
 // http://developer.apple.com/documentation/mac/QuickDraw/QuickDraw-461.html
 
-MystPICT::MystPICT(JPEGDecoder *jpegDecoder) {
+MystPICT::MystPICT(Graphics::JPEGDecoder *jpegDecoder) {
 	_jpegDecoder = jpegDecoder;
 	_pixelFormat = g_system->getScreenFormat();
 }
@@ -264,9 +264,6 @@
 	stream->seek(startPos + dataSize);
 
 	image->copyFrom(*jpegImage);
-
-	jpegImage->free();
-	delete jpegImage;
 }
 
 } // End of namespace Mohawk

Modified: scummvm/trunk/engines/mohawk/myst_pict.h
===================================================================
--- scummvm/trunk/engines/mohawk/myst_pict.h	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/engines/mohawk/myst_pict.h	2010-05-23 18:33:55 UTC (rev 49165)
@@ -32,18 +32,18 @@
 #include "graphics/pixelformat.h"
 #include "graphics/surface.h"
 
-#include "mohawk/jpeg.h"
+#include "graphics/video/codecs/mjpeg.h"
 
 namespace Mohawk {
 
 class MystPICT {
 public:
-	MystPICT(JPEGDecoder *jpegDecoder);
+	MystPICT(Graphics::JPEGDecoder *jpegDecoder);
 	~MystPICT() {}
 	Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
 
 private:
-	JPEGDecoder *_jpegDecoder;
+	Graphics::JPEGDecoder *_jpegDecoder;
 	Common::Rect _imageRect;
 	Graphics::PixelFormat _pixelFormat;
 

Modified: scummvm/trunk/engines/mohawk/myst_scripts.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/myst_scripts.cpp	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/engines/mohawk/myst_scripts.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -27,7 +27,7 @@
 #include "mohawk/graphics.h"
 #include "mohawk/myst_scripts.h"
 #include "mohawk/sound.h"
-#include "mohawk/video/video.h"
+#include "mohawk/video.h"
 
 #include "gui/message.h"
 

Modified: scummvm/trunk/engines/mohawk/riven.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/riven.cpp	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/engines/mohawk/riven.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -33,7 +33,7 @@
 #include "mohawk/riven_external.h"
 #include "mohawk/riven_saveload.h"
 #include "mohawk/dialogs.h"
-#include "mohawk/video/video.h"
+#include "mohawk/video.h"
 
 namespace Mohawk {
 

Modified: scummvm/trunk/engines/mohawk/riven_external.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/riven_external.cpp	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/engines/mohawk/riven_external.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -27,7 +27,7 @@
 #include "mohawk/riven.h"
 #include "mohawk/riven_external.h"
 #include "mohawk/sound.h"
-#include "mohawk/video/video.h"
+#include "mohawk/video.h"
 
 #include "gui/message.h"
 #include "common/events.h"

Modified: scummvm/trunk/engines/mohawk/riven_scripts.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/riven_scripts.cpp	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/engines/mohawk/riven_scripts.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -28,7 +28,7 @@
 #include "mohawk/riven_external.h"
 #include "mohawk/riven_scripts.h"
 #include "mohawk/sound.h"
-#include "mohawk/video/video.h"
+#include "mohawk/video.h"
 
 #include "common/stream.h"
 #include "graphics/cursorman.h"

Copied: scummvm/trunk/engines/mohawk/video.cpp (from rev 49161, scummvm/trunk/engines/mohawk/video/video.cpp)
===================================================================
--- scummvm/trunk/engines/mohawk/video.cpp	                        (rev 0)
+++ scummvm/trunk/engines/mohawk/video.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -0,0 +1,377 @@
+/* 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 "mohawk/resource.h"
+#include "mohawk/video.h"
+
+#include "common/events.h"
+#include "graphics/video/qt_decoder.h"
+
+namespace Mohawk {
+
+VideoManager::VideoManager(MohawkEngine* vm) : _vm(vm) {
+}
+
+VideoManager::~VideoManager() {
+	_mlstRecords.clear();
+	stopVideos();
+}
+
+void VideoManager::pauseVideos() {
+	for (uint16 i = 0; i < _videoStreams.size(); i++)
+		_videoStreams[i]->pauseVideo(true);
+}
+
+void VideoManager::resumeVideos() {
+	for (uint16 i = 0; i < _videoStreams.size(); i++)
+		_videoStreams[i]->pauseVideo(false);
+}
+
+void VideoManager::stopVideos() {
+	for (uint16 i = 0; i < _videoStreams.size(); i++)
+		delete _videoStreams[i].video;
+	_videoStreams.clear();
+}
+
+void VideoManager::playMovie(Common::String filename, uint16 x, uint16 y, bool clearScreen) {
+	VideoHandle videoHandle = createVideoHandle(filename, x, y, false);
+	if (videoHandle == NULL_VID_HANDLE)
+		return;
+
+	// Clear screen if requested
+	if (clearScreen) {
+		_vm->_system->fillScreen(_vm->_system->getScreenFormat().RGBToColor(0, 0, 0));
+		_vm->_system->updateScreen();
+	}
+
+	waitUntilMovieEnds(videoHandle);
+}
+
+void VideoManager::playMovieCentered(Common::String filename, bool clearScreen) {
+	VideoHandle videoHandle = createVideoHandle(filename, 0, 0, false);
+	if (videoHandle == NULL_VID_HANDLE)
+		return;
+
+	// Clear screen if requested
+	if (clearScreen) {
+		_vm->_system->fillScreen(_vm->_system->getScreenFormat().RGBToColor(0, 0, 0));
+		_vm->_system->updateScreen();
+	}
+
+	_videoStreams[videoHandle].x = (_vm->_system->getWidth() - _videoStreams[videoHandle]->getWidth()) / 2;
+	_videoStreams[videoHandle].y = (_vm->_system->getHeight() - _videoStreams[videoHandle]->getHeight()) / 2;
+
+	waitUntilMovieEnds(videoHandle);
+}
+
+void VideoManager::waitUntilMovieEnds(VideoHandle videoHandle) {
+	bool continuePlaying = true;
+
+	while (!_videoStreams[videoHandle]->endOfVideo() && !_vm->shouldQuit() && continuePlaying) {
+		if (updateBackgroundMovies())
+			_vm->_system->updateScreen();
+
+		Common::Event event;
+		while (_vm->_system->getEventManager()->pollEvent(event)) {
+			switch (event.type) {
+			case Common::EVENT_RTL:
+			case Common::EVENT_QUIT:
+				continuePlaying = false;
+				break;
+			case Common::EVENT_KEYDOWN:
+				switch (event.kbd.keycode) {
+				case Common::KEYCODE_SPACE:
+					_vm->pauseGame();
+					break;
+				case Common::KEYCODE_ESCAPE:
+					continuePlaying = false;
+					break;
+				default:
+					break;
+			}
+			default:
+				break;
+			}
+		}
+
+		// Cut down on CPU usage
+		_vm->_system->delayMillis(10);
+	}
+
+	_videoStreams[videoHandle]->close();
+	_videoStreams.clear();
+}
+
+void VideoManager::playBackgroundMovie(Common::String filename, int16 x, int16 y, bool loop) {
+	VideoHandle videoHandle = createVideoHandle(filename, x, y, loop);
+	if (videoHandle == NULL_VID_HANDLE)
+		return;
+
+	// Center x if requested
+	if (x < 0)
+		_videoStreams[videoHandle].x = (_vm->_system->getWidth() - _videoStreams[videoHandle]->getWidth()) / 2;
+
+	// Center y if requested
+	if (y < 0)
+		_videoStreams[videoHandle].y = (_vm->_system->getHeight() - _videoStreams[videoHandle]->getHeight()) / 2;
+}
+
+bool VideoManager::updateBackgroundMovies() {
+	bool updateScreen = false;
+
+	for (uint32 i = 0; i < _videoStreams.size() && !_vm->shouldQuit(); i++) {
+		// Skip deleted videos
+		if (!_videoStreams[i].video)
+			continue;
+
+		// Remove any videos that are over
+		if (_videoStreams[i]->endOfVideo()) {
+			if (_videoStreams[i].loop) {
+				_videoStreams[i]->rewind();
+			} else {
+				delete _videoStreams[i].video;
+				memset(&_videoStreams[i], 0, sizeof(VideoEntry));
+				_videoStreams[i].video = NULL;
+				continue;
+			}
+		}
+
+		// Check if we need to draw a frame
+		if (_videoStreams[i]->needsUpdate()) {
+			Graphics::Surface *frame = _videoStreams[i]->decodeNextFrame();
+			bool deleteFrame = false;
+
+			if (frame && _videoStreams[i].enabled) {
+				// Convert from 8bpp to the current screen format if necessary
+				if (frame->bytesPerPixel == 1) {
+					Graphics::Surface *newFrame = new Graphics::Surface();
+					Graphics::PixelFormat pixelFormat = _vm->_system->getScreenFormat();
+					byte *palette = _videoStreams[i]->getPalette();
+					assert(palette);
+
+					newFrame->create(frame->w, frame->h, pixelFormat.bytesPerPixel);
+
+					for (uint16 j = 0; j < frame->h; j++) {
+						for (uint16 k = 0; k < frame->w; k++) {
+							byte palIndex = *((byte *)frame->getBasePtr(k, j));
+							byte r = palette[palIndex * 3];
+							byte g = palette[palIndex * 3 + 1];
+							byte b = palette[palIndex * 3 + 2];
+							if (pixelFormat.bytesPerPixel == 2)
+								*((uint16 *)newFrame->getBasePtr(k, j)) = pixelFormat.RGBToColor(r, g, b);
+							else
+								*((uint32 *)newFrame->getBasePtr(k, j)) = pixelFormat.RGBToColor(r, g, b);
+						}
+					}
+
+					frame = newFrame;
+					deleteFrame = true;
+				}
+
+				// Clip the width/height to make sure we stay on the screen (Myst does this a few times)
+				uint16 width = MIN<int32>(_videoStreams[i]->getWidth(), _vm->_system->getWidth() - _videoStreams[i].x);
+				uint16 height = MIN<int32>(_videoStreams[i]->getHeight(), _vm->_system->getHeight() - _videoStreams[i].y);
+				_vm->_system->copyRectToScreen((byte*)frame->pixels, frame->pitch, _videoStreams[i].x, _videoStreams[i].y, width, height);
+
+				// We've drawn something to the screen, make sure we update it
+				updateScreen = true;
+
+				// Delete the frame if we're using the buffer from the 8bpp conversion
+				if (deleteFrame) {
+					frame->free();
+					delete frame;
+				}
+			}
+		}
+
+		// Update the audio buffer too
+		_videoStreams[i]->updateAudioBuffer();
+	}
+
+	// Return true if we need to update the screen
+	return updateScreen;
+}
+
+void VideoManager::activateMLST(uint16 mlstId, uint16 card) {
+	Common::SeekableReadStream *mlstStream = _vm->getRawData(ID_MLST, card);
+	uint16 recordCount = mlstStream->readUint16BE();
+
+	for (uint16 i = 0; i < recordCount; i++) {
+		MLSTRecord mlstRecord;
+		mlstRecord.index = mlstStream->readUint16BE();
+		mlstRecord.movieID = mlstStream->readUint16BE();
+		mlstRecord.code = mlstStream->readUint16BE();
+		mlstRecord.left = mlstStream->readUint16BE();
+		mlstRecord.top = mlstStream->readUint16BE();
+
+		for (byte j = 0; j < 2; j++)
+			if (mlstStream->readUint16BE() != 0)
+				warning("u0[%d] in MLST non-zero", j);
+
+		if (mlstStream->readUint16BE() != 0xFFFF)
+			warning("u0[2] in MLST not 0xFFFF");
+
+		mlstRecord.loop = mlstStream->readUint16BE();
+		mlstRecord.volume = mlstStream->readUint16BE();
+		mlstRecord.u1 = mlstStream->readUint16BE();
+
+		if (mlstRecord.u1 != 1)
+			warning("mlstRecord.u1 not 1");
+
+		if (mlstRecord.index == mlstId) {
+			_mlstRecords.push_back(mlstRecord);
+			break;
+		}
+	}
+
+	delete mlstStream;
+}
+
+void VideoManager::playMovie(uint16 id) {
+	for (uint16 i = 0; i < _mlstRecords.size(); i++)
+		if (_mlstRecords[i].code == id) {
+			debug(1, "Play tMOV %d (non-blocking) at (%d, %d) %s", _mlstRecords[i].movieID, _mlstRecords[i].left, _mlstRecords[i].top, _mlstRecords[i].loop != 0 ? "looping" : "non-looping");
+			createVideoHandle(_mlstRecords[i].movieID, _mlstRecords[i].left, _mlstRecords[i].top, _mlstRecords[i].loop != 0);
+			return;
+		}
+}
+
+void VideoManager::playMovieBlocking(uint16 id) {
+	for (uint16 i = 0; i < _mlstRecords.size(); i++)
+		if (_mlstRecords[i].code == id) {
+			debug(1, "Play tMOV %d (blocking) at (%d, %d)", _mlstRecords[i].movieID, _mlstRecords[i].left, _mlstRecords[i].top);
+			VideoHandle videoHandle = createVideoHandle(_mlstRecords[i].movieID, _mlstRecords[i].left, _mlstRecords[i].top, false);
+			waitUntilMovieEnds(videoHandle);
+			return;
+		}
+}
+
+void VideoManager::stopMovie(uint16 id) {
+	debug(2, "Stopping movie %d", id);
+	for (uint16 i = 0; i < _mlstRecords.size(); i++)
+		if (_mlstRecords[i].code == id)
+			for (uint16 j = 0; j < _videoStreams.size(); j++)
+				if (_mlstRecords[i].movieID == _videoStreams[j].id) {
+					delete _videoStreams[i].video;
+					memset(&_videoStreams[i].video, 0, sizeof(VideoEntry));
+					return;
+				}
+}
+
+void VideoManager::enableMovie(uint16 id) {
+	debug(2, "Enabling movie %d", id);
+	for (uint16 i = 0; i < _mlstRecords.size(); i++)
+		if (_mlstRecords[i].code == id)
+			for (uint16 j = 0; j < _videoStreams.size(); j++)
+				if (_mlstRecords[i].movieID == _videoStreams[j].id) {
+					_videoStreams[j].enabled = true;
+					return;
+				}
+}
+
+void VideoManager::disableMovie(uint16 id) {
+	debug(2, "Disabling movie %d", id);
+	for (uint16 i = 0; i < _mlstRecords.size(); i++)
+		if (_mlstRecords[i].code == id)
+			for (uint16 j = 0; j < _videoStreams.size(); j++)
+				if (_mlstRecords[i].movieID == _videoStreams[j].id) {
+					_videoStreams[j].enabled = false;
+					return;
+				}
+}
+
+void VideoManager::disableAllMovies() {
+	debug(2, "Disabling all movies");
+	for (uint16 i = 0; i < _videoStreams.size(); i++)
+		_videoStreams[i].enabled = false;
+}
+
+VideoHandle VideoManager::createVideoHandle(uint16 id, uint16 x, uint16 y, bool loop) {
+	// First, check to see if that video is already playing
+	for (uint32 i = 0; i < _videoStreams.size(); i++)
+		if (_videoStreams[i].id == id)
+			return i;
+
+	// Otherwise, create a new entry
+	VideoEntry entry;
+	entry.video = new Graphics::QuickTimeDecoder();
+	entry.x = x;
+	entry.y = y;
+	entry.filename = "";
+	entry.id = id;
+	entry.loop = loop;
+	entry.enabled = true;
+	entry->setChunkBeginOffset(_vm->getResourceOffset(ID_TMOV, id));
+	entry->load(*_vm->getRawData(ID_TMOV, id));
+
+	// Search for any deleted videos so we can take a formerly used slot
+	for (uint32 i = 0; i < _videoStreams.size(); i++)
+		if (!_videoStreams[i].video) {
+			_videoStreams[i] = entry;
+			return i;
+		}
+
+	// Otherwise, just add it to the list
+	_videoStreams.push_back(entry);
+	return _videoStreams.size() - 1;
+}
+
+VideoHandle VideoManager::createVideoHandle(Common::String filename, uint16 x, uint16 y, bool loop) {
+	// First, check to see if that video is already playing
+	for (uint32 i = 0; i < _videoStreams.size(); i++)
+		if (_videoStreams[i].filename == filename)
+			return i;
+
+	// Otherwise, create a new entry
+	VideoEntry entry;
+	entry.video = new Graphics::QuickTimeDecoder();
+	entry.x = x;
+	entry.y = y;
+	entry.filename = filename;
+	entry.id = 0;
+	entry.loop = loop;
+	entry.enabled = true;
+	
+	Common::File *file = new Common::File();
+	if (!file->open(filename)) {
+		delete file;
+		return NULL_VID_HANDLE;
+	}
+	
+	entry->load(*file);
+	
+	// Search for any deleted videos so we can take a formerly used slot
+	for (uint32 i = 0; i < _videoStreams.size(); i++)
+		if (!_videoStreams[i].video) {
+			_videoStreams[i] = entry;
+			return i;
+		}
+			
+	// Otherwise, just add it to the list
+	_videoStreams.push_back(entry);
+	return _videoStreams.size() - 1;
+}
+
+} // End of namespace Mohawk

Copied: scummvm/trunk/engines/mohawk/video.h (from rev 49161, scummvm/trunk/engines/mohawk/video/video.h)
===================================================================
--- scummvm/trunk/engines/mohawk/video.h	                        (rev 0)
+++ scummvm/trunk/engines/mohawk/video.h	2010-05-23 18:33:55 UTC (rev 49165)
@@ -0,0 +1,109 @@
+/* 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 MOHAWK_VIDEO_H
+#define MOHAWK_VIDEO_H
+
+#include "graphics/pixelformat.h"
+
+namespace Graphics {
+	class QuickTimeDecoder;
+}
+
+namespace Mohawk {
+
+class MohawkEngine;
+
+struct MLSTRecord {
+	uint16 index;
+	uint16 movieID;
+	uint16 code;
+	uint16 left;
+	uint16 top;
+	uint16 u0[3];
+	uint16 loop;
+	uint16 volume;
+	uint16 u1;
+};
+
+struct VideoEntry {
+	Graphics::QuickTimeDecoder *video;
+	uint16 x;
+	uint16 y;
+	bool loop;
+	Common::String filename;
+	uint16 id; // Riven only
+	bool enabled;
+
+	Graphics::QuickTimeDecoder *operator->() const { assert(video); return video; }
+};
+
+typedef int32 VideoHandle;
+
+enum {
+	NULL_VID_HANDLE = -1
+};
+
+class VideoManager {
+public:
+	VideoManager(MohawkEngine *vm);
+	~VideoManager();
+
+	// Generic movie functions
+	void playMovie(Common::String filename, uint16 x = 0, uint16 y = 0, bool clearScreen = false);
+	void playMovieCentered(Common::String filename, bool clearScreen = true);
+	void playBackgroundMovie(Common::String filename, int16 x = -1, int16 y = -1, bool loop = false);
+	bool updateBackgroundMovies();
+	void pauseVideos();
+	void resumeVideos();
+	void stopVideos();
+
+	// Riven-related functions
+	void activateMLST(uint16 mlstId, uint16 card);
+	void enableMovie(uint16 id);
+	void disableMovie(uint16 id);
+	void disableAllMovies();
+	void playMovie(uint16 id);
+	void stopMovie(uint16 id);
+	void playMovieBlocking(uint16 id);
+
+	// Riven-related variables
+	Common::Array<MLSTRecord> _mlstRecords;
+
+private:
+	MohawkEngine *_vm;
+
+	void waitUntilMovieEnds(VideoHandle videoHandle);
+
+	// Keep tabs on any videos playing
+	Common::Array<VideoEntry> _videoStreams;
+
+	VideoHandle createVideoHandle(uint16 id, uint16 x, uint16 y, bool loop);
+	VideoHandle createVideoHandle(Common::String filename, uint16 x, uint16 y, bool loop);
+};
+
+} // End of namespace Mohawk
+
+#endif

Modified: scummvm/trunk/graphics/conversion.h
===================================================================
--- scummvm/trunk/graphics/conversion.h	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/graphics/conversion.h	2010-05-23 18:33:55 UTC (rev 49165)
@@ -45,13 +45,6 @@
 	v = CLIP<int>( ((r * 512) >> 10) - ((g * 429) >> 10) - ((b *  83) >> 10) + 128, 0, 255);
 }
 
-/** Converting a color from YUV to RGB colorspace, Cinepak style. */
-inline static void CPYUV2RGB(byte y, byte u, byte v, byte &r, byte &g, byte &b) {
-	r = CLIP<int>(y + 2 * (v - 128), 0, 255);
-	g = CLIP<int>(y - (u - 128) / 2 - (v - 128), 0, 255);
-	b = CLIP<int>(y + 2 * (u - 128), 0, 255);
-}
-
 // TODO: generic YUV to RGB blit
 
 /**

Modified: scummvm/trunk/graphics/module.mk
===================================================================
--- scummvm/trunk/graphics/module.mk	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/graphics/module.mk	2010-05-23 18:33:55 UTC (rev 49165)
@@ -25,10 +25,16 @@
 	video/dxa_decoder.o \
 	video/flic_decoder.o \
 	video/mpeg_player.o \
+	video/qt_decoder.o \
 	video/smk_decoder.o \
 	video/video_decoder.o \
+	video/codecs/cinepak.o \
+	video/codecs/mjpeg.o \
 	video/codecs/msrle.o \
 	video/codecs/msvideo1.o \
+	video/codecs/qtrle.o \
+	video/codecs/rpza.o \
+	video/codecs/smc.o \
 	video/coktelvideo/indeo3.o \
 	video/coktelvideo/coktelvideo.o
 

Modified: scummvm/trunk/graphics/video/avi_decoder.cpp
===================================================================
--- scummvm/trunk/graphics/video/avi_decoder.cpp	2010-05-23 18:03:23 UTC (rev 49164)
+++ scummvm/trunk/graphics/video/avi_decoder.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -35,6 +35,7 @@
 #include "graphics/video/avi_decoder.h"
 
 // Codecs
+#include "graphics/video/codecs/cinepak.h"
 #include "graphics/video/codecs/msvideo1.h"
 #include "graphics/video/codecs/msrle.h"
 
@@ -379,6 +380,8 @@
 			return new MSVideo1Decoder(_bmInfo.width, _bmInfo.height, _bmInfo.bitCount);
 		case ID_RLE :
 			return new MSRLEDecoder(_bmInfo.width, _bmInfo.height, _bmInfo.bitCount);
+		case ID_CVID:
+			return new CinepakDecoder();
 		default:
 			warning ("Unknown/Unhandled compression format \'%s\'", tag2str(_vidsHeader.streamHandler));
 	}

Copied: scummvm/trunk/graphics/video/codecs/cinepak.cpp (from rev 49161, scummvm/trunk/engines/mohawk/video/cinepak.cpp)
===================================================================
--- scummvm/trunk/graphics/video/codecs/cinepak.cpp	                        (rev 0)
+++ scummvm/trunk/graphics/video/codecs/cinepak.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -0,0 +1,287 @@
+/* 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 "graphics/video/codecs/cinepak.h"
+
+#include "common/system.h"
+
+// Code here partially based off of ffmpeg ;)
+
+namespace Graphics {
+
+// Convert a color from YUV to RGB colorspace, Cinepak style.
+inline static void CPYUV2RGB(byte y, byte u, byte v, byte &r, byte &g, byte &b) {
+	r = CLIP<int>(y + 2 * (v - 128), 0, 255);
+	g = CLIP<int>(y - (u - 128) / 2 - (v - 128), 0, 255);
+	b = CLIP<int>(y + 2 * (u - 128), 0, 255);
+}
+
+#define PUT_PIXEL(offset, lum, u, v) \
+	CPYUV2RGB(lum, u, v, r, g, b); \
+	if (_pixelFormat.bytesPerPixel == 2) \
+		*((uint16 *)_curFrame.surface->pixels + offset) = _pixelFormat.RGBToColor(r, g, b); \
+	else \
+		*((uint32 *)_curFrame.surface->pixels + offset) = _pixelFormat.RGBToColor(r, g, b)
+
+CinepakDecoder::CinepakDecoder() : Codec() {
+	_curFrame.surface = NULL;
+	_curFrame.strips = NULL;
+	_y = 0;
+	_pixelFormat = g_system->getScreenFormat();
+}
+
+CinepakDecoder::~CinepakDecoder() {
+	if (_curFrame.surface)
+		_curFrame.surface->free();
+	delete[] _curFrame.strips;
+}
+
+Surface *CinepakDecoder::decodeImage(Common::SeekableReadStream *stream) {
+	_curFrame.flags = stream->readByte();
+	_curFrame.length = (stream->readByte() << 16) + stream->readUint16BE();
+	_curFrame.width = stream->readUint16BE();
+	_curFrame.height = stream->readUint16BE();
+	_curFrame.stripCount = stream->readUint16BE();
+
+	if (_curFrame.strips == NULL)
+		_curFrame.strips = new CinepakStrip[_curFrame.stripCount];
+
+	debug (4, "Cinepak Frame: Width = %d, Height = %d, Strip Count = %d", _curFrame.width, _curFrame.height, _curFrame.stripCount);
+
+#if 0
+	// Borrowed from FFMPEG. This should cut out the extra data Cinepak for Sega has (which is useless).
+	// The theory behind this is that this is here to confuse standard Cinepak decoders. But, we won't let that happen! ;)
+	if (_curFrame.length != (uint32)stream->size()) {
+		if (stream->readUint16BE() == 0xFE00)
+			stream->readUint32BE();
+	}
+#endif
+
+	if (!_curFrame.surface) {
+		_curFrame.surface = new Surface();
+		_curFrame.surface->create(_curFrame.width, _curFrame.height, _pixelFormat.bytesPerPixel);
+	}
+
+	// Reset the y variable.
+	_y = 0;
+
+	for (uint16 i = 0; i < _curFrame.stripCount; i++) {
+		if (i > 0 && !(_curFrame.flags & 1)) { // Use codebooks from last strip
+			for (uint16 j = 0; j < 256; j++) {
+				_curFrame.strips[i].v1_codebook[j] = _curFrame.strips[i - 1].v1_codebook[j];
+				_curFrame.strips[i].v4_codebook[j] = _curFrame.strips[i - 1].v4_codebook[j];
+			}
+		}
+
+		_curFrame.strips[i].id = stream->readUint16BE();
+		_curFrame.strips[i].length = stream->readUint16BE() - 12; // Subtract the 12 byte header
+		_curFrame.strips[i].rect.top = _y; stream->readUint16BE(); // Ignore, substitute with our own.
+		_curFrame.strips[i].rect.left = 0; stream->readUint16BE(); // Ignore, substitute with our own
+		_curFrame.strips[i].rect.bottom = _y + stream->readUint16BE();
+		_curFrame.strips[i].rect.right = _curFrame.width; stream->readUint16BE(); // Ignore, substitute with our own
+
+		//printf ("Left = %d, Top = %d, Right = %d, Bottom = %d\n", _curFrame.strips[i].rect.left, _curFrame.strips[i].rect.top, _curFrame.strips[i].rect.right, _curFrame.strips[i].rect.bottom);
+
+		// Sanity check. Because Cinepak is based on 4x4 blocks, the width and height of each strip needs to be divisible by 4.
+		assert(!(_curFrame.strips[i].rect.width() % 4) && !(_curFrame.strips[i].rect.height() % 4));
+
+		uint32 pos = stream->pos();
+
+		while ((uint32)stream->pos() < (pos + _curFrame.strips[i].length) && !stream->eos()) {
+			byte chunkID = stream->readByte();
+
+			if (stream->eos())
+				break;
+
+			// Chunk Size is 24-bit, ignore the first 4 bytes
+			uint32 chunkSize = stream->readByte() << 16;
+			chunkSize += stream->readUint16BE() - 4;
+
+			int32 startPos = stream->pos();
+
+			switch (chunkID) {
+			case 0x20:
+			case 0x21:
+			case 0x24:
+			case 0x25:
+				loadCodebook(stream, i, 4, chunkID, chunkSize);
+				break;
+			case 0x22:
+			case 0x23:
+			case 0x26:
+			case 0x27:
+				loadCodebook(stream, i, 1, chunkID, chunkSize);
+				break;
+			case 0x30:
+			case 0x31:
+			case 0x32:
+				decodeVectors(stream, i, chunkID, chunkSize);
+				break;
+			default:
+				warning("Unknown Cinepak chunk ID %02x", chunkID);
+				return _curFrame.surface;
+			}
+
+			if (stream->pos() != startPos + (int32)chunkSize)
+				stream->seek(startPos + chunkSize);
+		}
+
+		_y = _curFrame.strips[i].rect.bottom;
+	}
+
+	return _curFrame.surface;
+}
+
+void CinepakDecoder::loadCodebook(Common::SeekableReadStream *stream, uint16 strip, byte codebookType, byte chunkID, uint32 chunkSize) {
+	CinepakCodebook *codebook = (codebookType == 1) ? _curFrame.strips[strip].v1_codebook : _curFrame.strips[strip].v4_codebook;
+
+	int32 startPos = stream->pos();
+	uint32 flag = 0, mask = 0;
+
+	for (uint16 i = 0; i < 256; i++) {
+		if ((chunkID & 0x01) && !(mask >>= 1)) {
+			if ((stream->pos() - startPos + 4) > (int32)chunkSize)
+				break;
+
+			flag  = stream->readUint32BE();
+			mask  = 0x80000000;
+		}
+
+		if (!(chunkID & 0x01) || (flag & mask)) {
+			byte n = (chunkID & 0x04) ? 4 : 6;
+			if ((stream->pos() - startPos + n) > (int32)chunkSize)
+				break;
+
+			for (byte j = 0; j < 4; j++)
+				codebook[i].y[j] = stream->readByte();
+
+			if (n == 6) {
+				codebook[i].u  = stream->readByte() + 128;
+				codebook[i].v  = stream->readByte() + 128;
+			} else {
+				/* this codebook type indicates either greyscale or
+				 * palettized video; if palettized, U & V components will
+				 * not be used so it is safe to set them to 128 for the
+				 * benefit of greyscale rendering in YUV420P */
+				codebook[i].u  = 128;
+				codebook[i].v  = 128;
+			}
+		}
+	}
+}
+
+void CinepakDecoder::decodeVectors(Common::SeekableReadStream *stream, uint16 strip, byte chunkID, uint32 chunkSize) {
+	uint32 flag = 0, mask = 0;
+	uint32 iy[4];
+	int32 startPos = stream->pos();
+	byte r = 0, g = 0, b = 0;
+
+	for (uint16 y = _curFrame.strips[strip].rect.top; y < _curFrame.strips[strip].rect.bottom; y += 4) {
+		iy[0] = _curFrame.strips[strip].rect.left + y * _curFrame.width;
+		iy[1] = iy[0] + _curFrame.width;
+		iy[2] = iy[1] + _curFrame.width;
+		iy[3] = iy[2] + _curFrame.width;
+
+		for (uint16 x = _curFrame.strips[strip].rect.left; x < _curFrame.strips[strip].rect.right; x += 4) {
+			if ((chunkID & 0x01) && !(mask >>= 1)) {
+				if ((stream->pos() - startPos + 4) > (int32)chunkSize)
+					return;
+
+				flag  = stream->readUint32BE();
+				mask  = 0x80000000;
+			}
+
+			if (!(chunkID & 0x01) || (flag & mask)) {
+				if (!(chunkID & 0x02) && !(mask >>= 1)) {
+					if ((stream->pos() - startPos + 4) > (int32)chunkSize)
+						return;
+
+					flag  = stream->readUint32BE();
+					mask  = 0x80000000;
+				}
+
+				if ((chunkID & 0x02) || (~flag & mask)) {
+					if ((stream->pos() - startPos + 1) > (int32)chunkSize)
+						return;
+
+					// Get the codebook
+					CinepakCodebook codebook = _curFrame.strips[strip].v1_codebook[stream->readByte()];
+
+					PUT_PIXEL(iy[0] + 0, codebook.y[0], codebook.u, codebook.v);
+					PUT_PIXEL(iy[0] + 1, codebook.y[0], codebook.u, codebook.v);
+					PUT_PIXEL(iy[1] + 0, codebook.y[0], codebook.u, codebook.v);
+					PUT_PIXEL(iy[1] + 1, codebook.y[0], codebook.u, codebook.v);
+
+					PUT_PIXEL(iy[0] + 2, codebook.y[1], codebook.u, codebook.v);
+					PUT_PIXEL(iy[0] + 3, codebook.y[1], codebook.u, codebook.v);
+					PUT_PIXEL(iy[1] + 2, codebook.y[1], codebook.u, codebook.v);
+					PUT_PIXEL(iy[1] + 3, codebook.y[1], codebook.u, codebook.v);
+
+					PUT_PIXEL(iy[2] + 0, codebook.y[2], codebook.u, codebook.v);
+					PUT_PIXEL(iy[2] + 1, codebook.y[2], codebook.u, codebook.v);
+					PUT_PIXEL(iy[3] + 0, codebook.y[2], codebook.u, codebook.v);
+					PUT_PIXEL(iy[3] + 1, codebook.y[2], codebook.u, codebook.v);
+
+					PUT_PIXEL(iy[2] + 2, codebook.y[3], codebook.u, codebook.v);
+					PUT_PIXEL(iy[2] + 3, codebook.y[3], codebook.u, codebook.v);
+					PUT_PIXEL(iy[3] + 2, codebook.y[3], codebook.u, codebook.v);
+					PUT_PIXEL(iy[3] + 3, codebook.y[3], codebook.u, codebook.v);
+				} else if (flag & mask) {
+					if ((stream->pos() - startPos + 4) > (int32)chunkSize)
+						return;
+
+					CinepakCodebook codebook = _curFrame.strips[strip].v4_codebook[stream->readByte()];
+					PUT_PIXEL(iy[0] + 0, codebook.y[0], codebook.u, codebook.v);
+					PUT_PIXEL(iy[0] + 1, codebook.y[1], codebook.u, codebook.v);
+					PUT_PIXEL(iy[1] + 0, codebook.y[2], codebook.u, codebook.v);
+					PUT_PIXEL(iy[1] + 1, codebook.y[3], codebook.u, codebook.v);
+
+					codebook = _curFrame.strips[strip].v4_codebook[stream->readByte()];
+					PUT_PIXEL(iy[0] + 2, codebook.y[0], codebook.u, codebook.v);
+					PUT_PIXEL(iy[0] + 3, codebook.y[1], codebook.u, codebook.v);
+					PUT_PIXEL(iy[1] + 2, codebook.y[2], codebook.u, codebook.v);
+					PUT_PIXEL(iy[1] + 3, codebook.y[3], codebook.u, codebook.v);
+
+					codebook = _curFrame.strips[strip].v4_codebook[stream->readByte()];
+					PUT_PIXEL(iy[2] + 0, codebook.y[0], codebook.u, codebook.v);
+					PUT_PIXEL(iy[2] + 1, codebook.y[1], codebook.u, codebook.v);
+					PUT_PIXEL(iy[3] + 0, codebook.y[2], codebook.u, codebook.v);
+					PUT_PIXEL(iy[3] + 1, codebook.y[3], codebook.u, codebook.v);
+
+					codebook = _curFrame.strips[strip].v4_codebook[stream->readByte()];
+					PUT_PIXEL(iy[2] + 2, codebook.y[0], codebook.u, codebook.v);
+					PUT_PIXEL(iy[2] + 3, codebook.y[1], codebook.u, codebook.v);
+					PUT_PIXEL(iy[3] + 2, codebook.y[2], codebook.u, codebook.v);
+					PUT_PIXEL(iy[3] + 3, codebook.y[3], codebook.u, codebook.v);
+				}
+			}
+
+			for (byte i = 0; i < 4; i++)
+				iy[i] += 4;
+		}
+	}
+}
+
+} // End of namespace Graphics

Copied: scummvm/trunk/graphics/video/codecs/cinepak.h (from rev 49161, scummvm/trunk/engines/mohawk/video/cinepak.h)
===================================================================
--- scummvm/trunk/graphics/video/codecs/cinepak.h	                        (rev 0)
+++ scummvm/trunk/graphics/video/codecs/cinepak.h	2010-05-23 18:33:55 UTC (rev 49165)
@@ -0,0 +1,81 @@
+/* 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_CINEPAK_H
+#define GRAPHICS_CINEPAK_H
+
+#include "common/scummsys.h"
+#include "common/stream.h"
+#include "common/rect.h"
+#include "graphics/surface.h"
+#include "graphics/pixelformat.h"
+
+#include "graphics/video/codecs/codec.h"
+
+namespace Graphics {
+
+struct CinepakCodebook {
+	byte y[4];
+	byte u, v;
+};
+
+struct CinepakStrip {
+	uint16 id;
+	uint16 length;
+	Common::Rect rect;
+	CinepakCodebook v1_codebook[256], v4_codebook[256];
+};
+
+struct CinepakFrame {
+	byte flags;
+	uint32 length;
+	uint16 width;
+	uint16 height;
+	uint16 stripCount;
+	CinepakStrip *strips;
+
+	Surface *surface;
+};
+
+class CinepakDecoder : public Codec {
+public:
+	CinepakDecoder();
+	~CinepakDecoder();
+
+	Surface *decodeImage(Common::SeekableReadStream *stream);
+	PixelFormat getPixelFormat() const { return _pixelFormat; }
+
+private:
+	CinepakFrame _curFrame;
+	int32 _y;
+	PixelFormat _pixelFormat;
+
+	void loadCodebook(Common::SeekableReadStream *stream, uint16 strip, byte codebookType, byte chunkID, uint32 chunkSize);
+	void decodeVectors(Common::SeekableReadStream *stream, uint16 strip, byte chunkID, uint32 chunkSize);
+};
+
+} // End of namespace Graphics
+
+#endif

Copied: scummvm/trunk/graphics/video/codecs/mjpeg.cpp (from rev 49161, scummvm/trunk/engines/mohawk/jpeg.cpp)
===================================================================
--- scummvm/trunk/graphics/video/codecs/mjpeg.cpp	                        (rev 0)
+++ scummvm/trunk/graphics/video/codecs/mjpeg.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -0,0 +1,73 @@
+/* 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/system.h"
+#include "graphics/conversion.h" // For YUV2RGB
+
+#include "graphics/video/codecs/mjpeg.h"
+
+namespace Graphics {
+
+JPEGDecoder::JPEGDecoder() : Codec() {
+	_jpeg = new JPEG();
+	_pixelFormat = g_system->getScreenFormat();
+	_surface = NULL;
+}
+
+JPEGDecoder::~JPEGDecoder() {
+	delete _jpeg;
+
+	if (_surface) {
+		_surface->free();
+		delete _surface;
+	}
+}
+
+Surface *JPEGDecoder::decodeImage(Common::SeekableReadStream* stream) {
+	_jpeg->read(stream);
+	Surface *ySurface = _jpeg->getComponent(1);
+	Surface *uSurface = _jpeg->getComponent(2);
+	Surface *vSurface = _jpeg->getComponent(3);
+
+	if (!_surface) {
+		_surface = new Surface();
+		_surface->create(ySurface->w, ySurface->h, _pixelFormat.bytesPerPixel);
+	}
+
+	for (uint16 i = 0; i < _surface->h; i++) {
+		for (uint16 j = 0; j < _surface->w; j++) {
+			byte r = 0, g = 0, b = 0;
+			YUV2RGB(*((byte *)ySurface->getBasePtr(j, i)), *((byte *)uSurface->getBasePtr(j, i)), *((byte *)vSurface->getBasePtr(j, i)), r, g, b);
+			if (_pixelFormat.bytesPerPixel == 2)
+				*((uint16 *)_surface->getBasePtr(j, i)) = _pixelFormat.RGBToColor(r, g, b);
+			else
+				*((uint32 *)_surface->getBasePtr(j, i)) = _pixelFormat.RGBToColor(r, g, b);
+		}
+	}
+
+	return _surface;
+}
+
+} // End of namespace Graphics

Copied: scummvm/trunk/graphics/video/codecs/mjpeg.h (from rev 49161, scummvm/trunk/engines/mohawk/jpeg.h)
===================================================================
--- scummvm/trunk/graphics/video/codecs/mjpeg.h	                        (rev 0)
+++ scummvm/trunk/graphics/video/codecs/mjpeg.h	2010-05-23 18:33:55 UTC (rev 49165)
@@ -0,0 +1,58 @@
+/* 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_MJPEG_H
+#define GRAPHICS_MJPEG_H
+
+#include "common/scummsys.h"
+#include "common/stream.h"
+
+#include "graphics/video/codecs/codec.h"
+#include "graphics/jpeg.h"
+#include "graphics/pixelformat.h"
+
+namespace Graphics {
+
+// Motion JPEG Decoder
+// Basically a wrapper around JPEG which converts to RGB and also functions
+// as a Codec.
+
+class JPEGDecoder : public Codec {
+public:
+	JPEGDecoder();
+	~JPEGDecoder();
+
+	Surface *decodeImage(Common::SeekableReadStream *stream);
+	PixelFormat getPixelFormat() const { return _pixelFormat; }
+
+private:
+	PixelFormat _pixelFormat;
+	JPEG *_jpeg;
+	Surface *_surface;
+};
+
+} // End of namespace Graphics
+
+#endif

Copied: scummvm/trunk/graphics/video/codecs/qtrle.cpp (from rev 49161, scummvm/trunk/engines/mohawk/video/qtrle.cpp)
===================================================================
--- scummvm/trunk/graphics/video/codecs/qtrle.cpp	                        (rev 0)
+++ scummvm/trunk/graphics/video/codecs/qtrle.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -0,0 +1,420 @@
+/* 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$
+ *
+ */
+
+// QuickTime RLE Decoder
+// Based off ffmpeg's QuickTime RLE decoder (written by Mike Melanson)
+
+#include "graphics/video/codecs/qtrle.h"
+
+#include "common/scummsys.h"
+#include "common/stream.h"
+#include "common/system.h"
+#include "graphics/colormasks.h"
+#include "graphics/surface.h"
+
+namespace Graphics {
+
+QTRLEDecoder::QTRLEDecoder(uint16 width, uint16 height, byte bitsPerPixel) : Codec() {
+	_bitsPerPixel = bitsPerPixel;
+	_pixelFormat = g_system->getScreenFormat();
+
+	// We need to increase the surface size to a multiple of 4
+	uint16 wMod = width % 4;
+	if(wMod != 0)
+		width += 4 - wMod;
+
+	debug(2, "QTRLE corrected width: %d", width);
+
+	_surface = new Surface();
+	_surface->create(width, height, _bitsPerPixel <= 8 ? 1 : _pixelFormat.bytesPerPixel);
+}
+
+#define CHECK_STREAM_PTR(n) \
+  if ((stream->pos() + n) > stream->size()) { \
+    warning ("Problem: stream out of bounds (%d >= %d)", stream->pos() + n, stream->size()); \
+    return; \
+  }
+
+#define CHECK_PIXEL_PTR(n) \
+  if ((int32)pixelPtr + n > _surface->w * _surface->h) { \
+    warning ("Problem: pixel ptr = %d, pixel limit = %d", pixelPtr + n, _surface->w * _surface->h); \
+    return; \
+  } \
+
+void QTRLEDecoder::decode1(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
+	uint32 pixelPtr = 0;
+	byte *rgb = (byte *)_surface->pixels;
+
+	while (linesToChange) {
+		CHECK_STREAM_PTR(2);
+		byte skip = stream->readByte();
+		int8 rleCode = stream->readSByte();
+
+		if (rleCode == 0)
+			break;
+
+		if (skip & 0x80) {
+			linesToChange--;
+			rowPtr += _surface->w;
+			pixelPtr = rowPtr + 2 * (skip & 0x7f);
+		} else
+			pixelPtr += 2 * skip;
+
+		if (rleCode < 0) {
+			// decode the run length code
+			rleCode = -rleCode;
+			// get the next 2 bytes from the stream, treat them as groups of 8 pixels, and output them rleCode times */
+			CHECK_STREAM_PTR(2);
+			byte pi0 = stream->readByte();
+			byte pi1 = stream->readByte();
+			CHECK_PIXEL_PTR(rleCode * 2);
+
+			while (rleCode--) {
+				rgb[pixelPtr++] = pi0;
+				rgb[pixelPtr++] = pi1;
+			}
+		} else {
+			// copy the same pixel directly to output 2 times
+			rleCode *= 2;
+			CHECK_STREAM_PTR(rleCode);
+			CHECK_PIXEL_PTR(rleCode);
+
+			while (rleCode--)
+				rgb[pixelPtr++] = stream->readByte();
+		}
+	}
+}
+
+void QTRLEDecoder::decode2_4(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange, byte bpp) {
+	uint32 pixelPtr = 0;
+	byte *rgb = (byte *)_surface->pixels;
+	byte numPixels = (bpp == 4) ? 8 : 16;
+
+	while (linesToChange--) {
+		CHECK_STREAM_PTR(2);
+		pixelPtr = rowPtr + (numPixels * (stream->readByte() - 1));
+
+		for (int8 rleCode = stream->readSByte(); rleCode != -1; rleCode = stream->readSByte()) {
+			if (rleCode == 0) {
+				// there's another skip code in the stream
+				CHECK_STREAM_PTR(1);
+				pixelPtr += (numPixels * (stream->readByte() - 1));
+			} else if (rleCode < 0) {
+				// decode the run length code
+				rleCode = -rleCode;
+
+				// get the next 4 bytes from the stream, treat them as palette indices, and output them rleCode times */
+				CHECK_STREAM_PTR(4);
+
+				byte pi[16]; // 16 palette indices
+
+				for (int8 i = numPixels - 1; i >= 0; i--) {
+					pi[numPixels - 1 - i] = (stream->readByte() >> ((i * bpp) & 0x07)) & ((1 << bpp) - 1);
+
+					// FIXME: Is this right?
+					//stream_ptr += ((i & ((num_pixels>>2)-1)) == 0);
+					if ((i & ((numPixels >> 2) - 1)) == 0)
+						stream->readByte();
+				}
+
+				CHECK_PIXEL_PTR(rleCode * numPixels);
+
+				while (rleCode--)
+					for (byte i = 0; i < numPixels; i++)
+						rgb[pixelPtr++] = pi[i];
+			} else {
+				// copy the same pixel directly to output 4 times
+				rleCode *= 4;
+				CHECK_STREAM_PTR(rleCode);
+				CHECK_PIXEL_PTR(rleCode * (numPixels >> 2));
+
+				while (rleCode--) {
+					byte temp = stream->readByte();
+					if (bpp == 4) {
+						rgb[pixelPtr++] = (temp >> 4) & 0x0f;
+						rgb[pixelPtr++] = temp & 0x0f;
+					} else {
+						rgb[pixelPtr++] = (temp >> 6) & 0x03;
+						rgb[pixelPtr++] = (temp >> 4) & 0x03;
+						rgb[pixelPtr++] = (temp >> 2) & 0x03;
+						rgb[pixelPtr++] = temp & 0x03;
+					}
+				}
+			}
+		}
+
+		rowPtr += _surface->w;
+	}
+}
+
+void QTRLEDecoder::decode8(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
+	uint32 pixelPtr = 0;
+	byte *rgb = (byte *)_surface->pixels;
+
+	while (linesToChange--) {
+		CHECK_STREAM_PTR(2);
+		pixelPtr = rowPtr + 4 * (stream->readByte() - 1);
+
+		for (int8 rleCode = stream->readSByte(); rleCode != -1; rleCode = stream->readSByte()) {
+			if (rleCode == 0) {
+				// there's another skip code in the stream
+				CHECK_STREAM_PTR(1);
+				pixelPtr += 4 * (stream->readByte() - 1);
+			} else if (rleCode < 0) {
+				// decode the run length code
+				rleCode = -rleCode;
+
+				// get the next 4 bytes from the stream, treat them as palette indices, and output them rleCode times
+				CHECK_STREAM_PTR(4);
+
+				byte pi[4];  // 4 palette indexes
+
+				for (byte i = 0; i < 4; i++)
+					pi[i] = stream->readByte();
+
+				CHECK_PIXEL_PTR(rleCode * 4);
+
+				while (rleCode--)
+					for (byte i = 0; i < 4; i++)
+						rgb[pixelPtr++] = pi[i];
+			} else {
+				// copy the same pixel directly to output 4 times
+				rleCode *= 4;
+				CHECK_STREAM_PTR(rleCode);
+				CHECK_PIXEL_PTR(rleCode);
+
+				while (rleCode--)
+					rgb[pixelPtr++] = stream->readByte();
+			}
+		}
+
+		rowPtr += _surface->w;
+	}
+}
+
+void QTRLEDecoder::decode16(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
+	uint32 pixelPtr = 0;
+	OverlayColor *rgb = (OverlayColor *)_surface->pixels;
+
+	while (linesToChange--) {
+		CHECK_STREAM_PTR(2);
+		pixelPtr = rowPtr + stream->readByte() - 1;
+
+		for (int8 rleCode = stream->readSByte(); rleCode != -1; rleCode = stream->readSByte()) {
+			if (rleCode == 0) {
+				// there's another skip code in the stream
+				CHECK_STREAM_PTR(1);
+				pixelPtr += stream->readByte() - 1;
+			} else if (rleCode < 0) {
+				// decode the run length code
+				rleCode = -rleCode;
+				CHECK_STREAM_PTR(2);
+
+				uint16 rgb16 = stream->readUint16BE();
+
+				CHECK_PIXEL_PTR(rleCode);
+
+				while (rleCode--) {
+					// Convert from RGB555 to the format specified by the Overlay
+					byte r = 0, g = 0, b = 0;
+					colorToRGB<ColorMasks<555> >(rgb16, r, g, b);
+					rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b);
+				}
+			} else {
+				CHECK_STREAM_PTR(rleCode * 2);
+				CHECK_PIXEL_PTR(rleCode);
+
+				// copy pixels directly to output
+				while (rleCode--) {
+					uint16 rgb16 = stream->readUint16BE();
+
+					// Convert from RGB555 to the format specified by the Overlay
+					byte r = 0, g = 0, b = 0;
+					colorToRGB<ColorMasks<555> >(rgb16, r, g, b);
+					rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b);
+				}
+			}
+		}
+
+		rowPtr += _surface->w;
+	}
+}
+
+void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
+	uint32 pixelPtr = 0;
+	OverlayColor *rgb = (OverlayColor *)_surface->pixels;
+
+	while (linesToChange--) {
+		CHECK_STREAM_PTR(2);
+		pixelPtr = rowPtr + stream->readByte() - 1;
+
+		for (int8 rleCode = stream->readSByte(); rleCode != -1; rleCode = stream->readSByte()) {
+			if (rleCode == 0) {
+				// there's another skip code in the stream
+				CHECK_STREAM_PTR(1);
+				pixelPtr += stream->readByte() - 1;
+			} else if (rleCode < 0) {
+				// decode the run length code
+				rleCode = -rleCode;
+
+				CHECK_STREAM_PTR(3);
+
+				byte r = stream->readByte();
+				byte g = stream->readByte();
+				byte b = stream->readByte();
+
+				CHECK_PIXEL_PTR(rleCode);
+
+				while (rleCode--)
+					rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b);
+			} else {
+				CHECK_STREAM_PTR(rleCode * 3);
+				CHECK_PIXEL_PTR(rleCode);
+
+				// copy pixels directly to output
+				while (rleCode--) {
+					byte r = stream->readByte();
+					byte g = stream->readByte();
+					byte b = stream->readByte();
+					rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b);
+				}
+			}
+		}
+
+		rowPtr += _surface->w;
+	}
+}
+
+void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
+	uint32 pixelPtr = 0;
+	OverlayColor *rgb = (OverlayColor *)_surface->pixels;
+
+	while (linesToChange--) {
+		CHECK_STREAM_PTR(2);
+		pixelPtr = rowPtr + stream->readByte() - 1;
+
+		for (int8 rleCode = stream->readSByte(); rleCode != -1; rleCode = stream->readSByte()) {
+			if (rleCode == 0) {
+				// there's another skip code in the stream
+				CHECK_STREAM_PTR(1);
+				pixelPtr += stream->readByte() - 1;
+			} else if (rleCode < 0) {
+				// decode the run length code
+				rleCode = -rleCode;
+
+				CHECK_STREAM_PTR(4);
+
+				byte a = stream->readByte();
+				byte r = stream->readByte();
+				byte g = stream->readByte();
+				byte b = stream->readByte();
+
+				CHECK_PIXEL_PTR(rleCode);
+
+				while (rleCode--)
+					rgb[pixelPtr++] = _pixelFormat.ARGBToColor(a, r, g, b);
+			} else {
+				CHECK_STREAM_PTR(rleCode * 4);
+				CHECK_PIXEL_PTR(rleCode);
+
+				// copy pixels directly to output
+				while (rleCode--) {
+					byte a = stream->readByte();
+					byte r = stream->readByte();
+					byte g = stream->readByte();
+					byte b = stream->readByte();
+					rgb[pixelPtr++] = _pixelFormat.ARGBToColor(a, r, g, b);
+				}
+			}
+		}
+
+		rowPtr += _surface->w;
+	}
+}
+
+Surface *QTRLEDecoder::decodeImage(Common::SeekableReadStream *stream) {
+	uint16 start_line = 0;
+	uint16 height = _surface->h;
+
+	// check if this frame is even supposed to change
+	if (stream->size() < 8)
+		return _surface;
+
+	// start after the chunk size
+	stream->readUint32BE();
+
+	// fetch the header
+	uint16 header = stream->readUint16BE();
+
+	// if a header is present, fetch additional decoding parameters
+	if (header & 8) {
+		if(stream->size() < 14)
+			return _surface;
+		start_line = stream->readUint16BE();
+		stream->readUint16BE(); // Unknown
+		height = stream->readUint16BE();
+		stream->readUint16BE(); // Unknown
+	}
+
+	uint32 row_ptr = _surface->w * start_line;
+
+	switch (_bitsPerPixel) {
+		case 1:
+		case 33:
+			decode1(stream, row_ptr, height);
+			break;
+		case 2:
+		case 34:
+			decode2_4(stream, row_ptr, height, 2);
+			break;
+		case 4:
+		case 36:
+			decode2_4(stream, row_ptr, height, 4);
+			break;
+		case 8:
+		case 40:
+			decode8(stream, row_ptr, height);
+			break;
+		case 16:
+			decode16(stream, row_ptr, height);
+			break;
+		case 24:
+			decode24(stream, row_ptr, height);
+			break;
+		case 32:
+			decode32(stream, row_ptr, height);
+			break;
+		default:
+			error ("Unsupported bits per pixel %d", _bitsPerPixel);
+	}
+
+	return _surface;
+}
+
+QTRLEDecoder::~QTRLEDecoder() {
+	_surface->free();
+}
+
+} // End of namespace Graphics

Copied: scummvm/trunk/graphics/video/codecs/qtrle.h (from rev 49161, scummvm/trunk/engines/mohawk/video/qtrle.h)
===================================================================
--- scummvm/trunk/graphics/video/codecs/qtrle.h	                        (rev 0)
+++ scummvm/trunk/graphics/video/codecs/qtrle.h	2010-05-23 18:33:55 UTC (rev 49165)
@@ -0,0 +1,58 @@
+/* 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_VIDEO_QTRLE_H
+#define GRAPHICS_VIDEO_QTRLE_H
+
+#include "graphics/pixelformat.h"
+#include "graphics/video/codecs/codec.h"
+
+namespace Graphics {
+
+class QTRLEDecoder : public Codec {
+public:
+	QTRLEDecoder(uint16 width, uint16 height, byte bitsPerPixel);
+	~QTRLEDecoder();
+
+	Surface *decodeImage(Common::SeekableReadStream *stream);
+	PixelFormat getPixelFormat() const { return _pixelFormat; }
+
+private:
+	byte _bitsPerPixel;
+
+	Surface *_surface;
+	PixelFormat _pixelFormat;
+
+	void decode1(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange);
+	void decode2_4(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange, byte bpp);
+	void decode8(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange);
+	void decode16(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange);
+	void decode24(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange);
+	void decode32(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange);
+};
+
+} // End of namespace Graphics
+
+#endif

Copied: scummvm/trunk/graphics/video/codecs/rpza.cpp (from rev 49161, scummvm/trunk/engines/mohawk/video/rpza.cpp)
===================================================================
--- scummvm/trunk/graphics/video/codecs/rpza.cpp	                        (rev 0)
+++ scummvm/trunk/graphics/video/codecs/rpza.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -0,0 +1,208 @@
+/* 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 RPZA decoder
+
+#include "graphics/video/codecs/rpza.h"
+
+#include "common/system.h"
+#include "graphics/colormasks.h"
+
+namespace Graphics {
+
+RPZADecoder::RPZADecoder(uint16 width, uint16 height) : Codec() {
+	_pixelFormat = g_system->getScreenFormat();
+
+	// We need to increase the surface size to a multiple of 4
+	uint16 wMod = width % 4;
+	if(wMod != 0)
+		width += 4 - wMod;
+
+	debug(2, "RPZA corrected width: %d", width);
+
+	_surface = new Surface();
+	_surface->create(width, height, _pixelFormat.bytesPerPixel);
+}
+
+#define ADVANCE_BLOCK() \
+	pixelPtr += 4; \
+	if (pixelPtr >= _surface->w) { \
+		pixelPtr = 0; \
+		rowPtr += _surface->w * 4; \
+	} \
+	totalBlocks--; \
+	if (totalBlocks < 0) \
+		error("block counter just went negative (this should not happen)") \
+
+// Convert from RGB555 to the format specified by the screen
+#define PUT_PIXEL(color) \
+	if ((int32)blockPtr < _surface->w * _surface->h) { \
+		byte r = 0, g = 0, b = 0; \
+		colorToRGB<ColorMasks<555> >(color, r, g, b); \
+		if (_pixelFormat.bytesPerPixel == 2) \
+			*((uint16 *)_surface->pixels + blockPtr) = _pixelFormat.RGBToColor(r, g, b); \
+		else \
+			*((uint32 *)_surface->pixels + blockPtr) = _pixelFormat.RGBToColor(r, g, b); \
+	} \
+	blockPtr++
+
+Surface *RPZADecoder::decodeImage(Common::SeekableReadStream *stream) {
+	uint16 colorA = 0, colorB = 0;
+	uint16 color4[4];
+
+	uint32 rowPtr = 0;
+	uint32 pixelPtr = 0;
+	uint32 blockPtr = 0;
+	uint32 rowInc = _surface->w - 4;
+	uint16 ta;
+	uint16 tb;
+
+	// First byte is always 0xe1. Warn if it's different
+	byte firstByte = stream->readByte();
+	if (firstByte != 0xe1)
+		warning("First RPZA chunk byte is 0x%02x instead of 0xe1", firstByte);
+
+	// Get chunk size, ingnoring first byte
+	uint32 chunkSize = stream->readUint16BE() << 8;
+	chunkSize += stream->readByte();
+
+	// If length mismatch use size from MOV file and try to decode anyway
+	if (chunkSize != (uint32)stream->size()) {
+		warning("MOV chunk size != encoded chunk size; using MOV chunk size");
+		chunkSize = stream->size();
+	}
+
+	// Number of 4x4 blocks in frame
+	int32 totalBlocks = ((_surface->w + 3) / 4) * ((_surface->h + 3) / 4);
+
+	// Process chunk data
+	while ((uint32)stream->pos() < chunkSize) {
+		byte opcode = stream->readByte(); // Get opcode
+		byte numBlocks = (opcode & 0x1f) + 1; // Extract block counter from opcode
+
+		// If opcode MSbit is 0, we need more data to decide what to do
+		if ((opcode & 0x80) == 0) {
+			colorA = (opcode << 8) | stream->readByte();
+			opcode = 0;
+			if (stream->readByte() & 0x80) {
+				// Must behave as opcode 110xxxxx, using colorA computed
+				// above. Use fake opcode 0x20 to enter switch block at
+				// the right place
+				opcode = 0x20;
+				numBlocks = 1;
+			}
+			stream->seek(-1, SEEK_CUR);
+		}
+
+		switch (opcode & 0xe0) {
+		case 0x80: // Skip blocks
+			while (numBlocks--) {
+				ADVANCE_BLOCK();
+			}
+			break;
+		case 0xa0: // Fill blocks with one color
+			colorA = stream->readUint16BE();
+			while (numBlocks--) {
+				blockPtr = rowPtr + pixelPtr;
+				for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
+					for (byte pixel_x = 0; pixel_x < 4; pixel_x++) {
+						PUT_PIXEL(colorA);
+					}
+					blockPtr += rowInc;
+				}
+				ADVANCE_BLOCK();
+			}
+			break;
+
+		// Fill blocks with 4 colors
+		case 0xc0:
+			colorA = stream->readUint16BE();
+		case 0x20:
+			colorB = stream->readUint16BE();
+
+			// Sort out the colors
+			color4[0] = colorB;
+			color4[1] = 0;
+			color4[2] = 0;
+			color4[3] = colorA;
+
+			// Red components
+			ta = (colorA >> 10) & 0x1F;
+			tb = (colorB >> 10) & 0x1F;
+			color4[1] |= ((11 * ta + 21 * tb) >> 5) << 10;
+			color4[2] |= ((21 * ta + 11 * tb) >> 5) << 10;
+
+			// Green components
+			ta = (colorA >> 5) & 0x1F;
+			tb = (colorB >> 5) & 0x1F;
+			color4[1] |= ((11 * ta + 21 * tb) >> 5) << 5;
+			color4[2] |= ((21 * ta + 11 * tb) >> 5) << 5;
+
+			// Blue components
+			ta = colorA & 0x1F;
+			tb = colorB & 0x1F;
+			color4[1] |= ((11 * ta + 21 * tb) >> 5);
+			color4[2] |= ((21 * ta + 11 * tb) >> 5);
+
+			while (numBlocks--) {
+				blockPtr = rowPtr + pixelPtr;
+				for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
+					byte index = stream->readByte();
+					for (byte pixel_x = 0; pixel_x < 4; pixel_x++){
+						byte idx = (index >> (2 * (3 - pixel_x))) & 0x03;
+						PUT_PIXEL(color4[idx]);
+					}
+					blockPtr += rowInc;
+				}
+				ADVANCE_BLOCK();
+			}
+			break;
+
+		// Fill block with 16 colors
+		case 0x00:
+			blockPtr = rowPtr + pixelPtr;
+			for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
+				for (byte pixel_x = 0; pixel_x < 4; pixel_x++){
+					// We already have color of upper left pixel
+					if (pixel_y != 0 || pixel_x != 0)
+						colorA = stream->readUint16BE();
+
+					PUT_PIXEL(colorA);
+				}
+				blockPtr += rowInc;
+			}
+			ADVANCE_BLOCK();
+			break;
+
+		// Unknown opcode
+		default:
+			error("Unknown opcode %02x in rpza chunk", opcode);
+		}
+	}
+
+	return _surface;
+}
+
+} // End of namespace Graphics

Copied: scummvm/trunk/graphics/video/codecs/rpza.h (from rev 49161, scummvm/trunk/engines/mohawk/video/rpza.h)
===================================================================
--- scummvm/trunk/graphics/video/codecs/rpza.h	                        (rev 0)
+++ scummvm/trunk/graphics/video/codecs/rpza.h	2010-05-23 18:33:55 UTC (rev 49165)
@@ -0,0 +1,49 @@
+/* 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_VIDEO_RPZA_H
+#define GRAPHICS_VIDEO_RPZA_H
+
+#include "graphics/pixelformat.h"
+#include "graphics/video/codecs/codec.h"
+
+namespace Graphics {
+
+class RPZADecoder : public Codec {
+public:
+	RPZADecoder(uint16 width, uint16 height);
+	~RPZADecoder() { delete _surface; }
+
+	Surface *decodeImage(Common::SeekableReadStream *stream);
+	PixelFormat getPixelFormat() const { return _pixelFormat; }
+
+private:
+	Surface *_surface;
+	PixelFormat _pixelFormat;
+};
+
+} // End of namespace Graphics
+
+#endif

Copied: scummvm/trunk/graphics/video/codecs/smc.cpp (from rev 49161, scummvm/trunk/engines/mohawk/video/smc.cpp)
===================================================================
--- scummvm/trunk/graphics/video/codecs/smc.cpp	                        (rev 0)
+++ scummvm/trunk/graphics/video/codecs/smc.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -0,0 +1,385 @@
+/* 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 SMC decoder
+
+#include "graphics/video/codecs/smc.h"
+
+namespace Graphics {
+
+#define GET_BLOCK_COUNT() \
+  (opcode & 0x10) ? (1 + stream->readByte()) : 1 + (opcode & 0x0F);
+
+#define ADVANCE_BLOCK() \
+{ \
+	pixelPtr += 4; \
+	if (pixelPtr >= _surface->w) { \
+		pixelPtr = 0; \
+		rowPtr += _surface->w * 4; \
+	} \
+	totalBlocks--; \
+	if (totalBlocks < 0) { \
+		warning("block counter just went negative (this should not happen)"); \
+		return _surface; \
+	} \
+}
+
+SMCDecoder::SMCDecoder(uint16 width, uint16 height) {
+	_surface = new Graphics::Surface();
+	_surface->create(width, height, 1);
+}
+
+Graphics::Surface *SMCDecoder::decodeImage(Common::SeekableReadStream *stream) {
+	byte *pixels = (byte *)_surface->pixels;
+
+	uint32 numBlocks = 0;
+	uint32 colorFlags = 0;
+	uint32 colorFlagsA = 0;
+	uint32 colorFlagsB = 0;
+
+	const uint16 rowInc = _surface->w - 4;
+	int32 rowPtr = 0;
+	int32 pixelPtr = 0;
+	uint32 blockPtr = 0;
+	uint32 prevBlockPtr = 0;
+	uint32 prevBlockPtr1 = 0, prevBlockPtr2 = 0;
+	byte prevBlockFlag = false;
+	byte pixel = 0;
+
+	uint32 colorPairIndex = 0;
+	uint32 colorQuadIndex = 0;
+	uint32 colorOctetIndex = 0;
+	uint32 colorTableIndex = 0;  // indices to color pair, quad, or octet tables
+
+	int32 chunkSize = stream->readUint32BE() & 0x00FFFFFF;
+	if (chunkSize != stream->size())
+		warning("MOV chunk size != SMC chunk size (%d != %d); ignoring SMC chunk size", chunkSize, stream->size());
+
+	int32 totalBlocks = ((_surface->w + 3) / 4) * ((_surface->h + 3) / 4);
+
+	// traverse through the blocks
+	while (totalBlocks != 0) {
+		// sanity checks
+
+		// make sure stream ptr hasn't gone out of bounds
+		if (stream->pos() > stream->size()) {
+			warning("SMC decoder just went out of bounds (stream ptr = %d, chunk size = %d)", stream->pos(), stream->size());
+			return _surface;
+		}
+
+		// make sure the row pointer hasn't gone wild
+		if (rowPtr >= _surface->w * _surface->h) {
+			warning("SMC decoder just went out of bounds (row ptr = %d, size = %d)", rowPtr, _surface->w * _surface->h);
+			return _surface;
+		}
+
+		byte opcode = stream->readByte();
+
+		switch (opcode & 0xF0) {
+		// skip n blocks
+		case 0x00:
+		case 0x10:
+			numBlocks = GET_BLOCK_COUNT();
+			while (numBlocks--) {
+				ADVANCE_BLOCK();
+			}
+			break;
+
+		// repeat last block n times
+		case 0x20:
+		case 0x30:
+			numBlocks = GET_BLOCK_COUNT();
+
+			// sanity check
+			if (rowPtr == 0 && pixelPtr == 0) {
+				warning("encountered repeat block opcode (%02X) but no blocks rendered yet", opcode & 0xF0);
+				break;
+			}
+
+			// figure out where the previous block started
+			if (pixelPtr == 0)
+				prevBlockPtr1 = (rowPtr - _surface->w * 4) + _surface->w - 4;
+			else
+				prevBlockPtr1 = rowPtr + pixelPtr - 4;
+
+			while (numBlocks--) {
+				blockPtr = rowPtr + pixelPtr;
+				prevBlockPtr = prevBlockPtr1;
+				for (byte y = 0; y < 4; y++) {
+					for (byte x = 0; x < 4; x++)
+						pixels[blockPtr++] = pixels[prevBlockPtr++];
+					blockPtr += rowInc;
+					prevBlockPtr += rowInc;
+				}
+				ADVANCE_BLOCK();
+			}
+			break;
+
+		// repeat previous pair of blocks n times
+		case 0x40:
+		case 0x50:
+			numBlocks = GET_BLOCK_COUNT();
+			numBlocks *= 2;
+
+			// sanity check
+			if (rowPtr == 0 && pixelPtr < 2 * 4) {
+				warning("encountered repeat block opcode (%02X) but not enough blocks rendered yet", opcode & 0xF0);
+				break;
+			}
+
+			// figure out where the previous 2 blocks started
+			if (pixelPtr == 0)
+				prevBlockPtr1 = (rowPtr - _surface->w * 4) + _surface->w - 4 * 2;
+			else if (pixelPtr == 4)
+				prevBlockPtr1 = (rowPtr - _surface->w * 4) + rowInc;
+			else
+				prevBlockPtr1 = rowPtr + pixelPtr - 4 * 2;
+
+			if (pixelPtr == 0)
+				prevBlockPtr2 = (rowPtr - _surface->w * 4) + rowInc;
+			else
+				prevBlockPtr2 = rowPtr + pixelPtr - 4;
+
+			prevBlockFlag = 0;
+			while (numBlocks--) {
+				blockPtr = rowPtr + pixelPtr;
+
+				if (prevBlockFlag)
+					prevBlockPtr = prevBlockPtr2;
+				else
+					prevBlockPtr = prevBlockPtr1;
+
+				prevBlockFlag = !prevBlockFlag;
+
+				for (byte y = 0; y < 4; y++) {
+					for (byte x = 0; x < 4; x++)
+						pixels[blockPtr++] = pixels[prevBlockPtr++];
+
+					blockPtr += rowInc;
+					prevBlockPtr += rowInc;
+				}
+				ADVANCE_BLOCK();
+			}
+			break;
+
+		// 1-color block encoding
+		case 0x60:
+		case 0x70:
+			numBlocks = GET_BLOCK_COUNT();
+			pixel = stream->readByte();
+
+			while (numBlocks--) {
+				blockPtr = rowPtr + pixelPtr;
+				for (byte y = 0; y < 4; y++) {
+					for (byte x = 0; x < 4; x++)
+						pixels[blockPtr++] = pixel;
+
+					blockPtr += rowInc;
+				}
+				ADVANCE_BLOCK();
+			}
+			break;
+
+		// 2-color block encoding
+		case 0x80:
+		case 0x90:
+			numBlocks = (opcode & 0x0F) + 1;
+
+			// figure out which color pair to use to paint the 2-color block
+			if ((opcode & 0xF0) == 0x80) {
+				// fetch the next 2 colors from bytestream and store in next
+				// available entry in the color pair table
+				for (byte i = 0; i < CPAIR; i++) {
+					pixel = stream->readByte();
+					colorTableIndex = CPAIR * colorPairIndex + i;
+					_colorPairs[colorTableIndex] = pixel;
+				}
+
+				// this is the base index to use for this block
+				colorTableIndex = CPAIR * colorPairIndex;
+				colorPairIndex++;
+
+				// wraparound
+				if (colorPairIndex == COLORS_PER_TABLE)
+					colorPairIndex = 0;
+			} else
+				colorTableIndex = CPAIR * stream->readByte();
+
+			while (numBlocks--) {
+				colorFlags = stream->readUint16BE();
+				uint16 flagMask = 0x8000;
+				blockPtr = rowPtr + pixelPtr;
+				for (byte y = 0; y < 4; y++) {
+					for (byte x = 0; x < 4; x++) {
+						if (colorFlags & flagMask)
+							pixel = colorTableIndex + 1;
+						else
+							pixel = colorTableIndex;
+
+						flagMask >>= 1;
+						pixels[blockPtr++] = _colorPairs[pixel];
+					}
+
+					blockPtr += rowInc;
+				}
+				ADVANCE_BLOCK();
+			}
+			break;
+
+		// 4-color block encoding
+		case 0xA0:
+		case 0xB0:
+			numBlocks = (opcode & 0x0F) + 1;
+
+			// figure out which color quad to use to paint the 4-color block
+			if ((opcode & 0xF0) == 0xA0) {
+				// fetch the next 4 colors from bytestream and store in next
+				// available entry in the color quad table
+				for (byte i = 0; i < CQUAD; i++) {
+					pixel = stream->readByte();
+					colorTableIndex = CQUAD * colorQuadIndex + i;
+					_colorQuads[colorTableIndex] = pixel;
+				}
+
+				// this is the base index to use for this block
+				colorTableIndex = CQUAD * colorQuadIndex;
+				colorQuadIndex++;
+
+				// wraparound
+				if (colorQuadIndex == COLORS_PER_TABLE)
+					colorQuadIndex = 0;
+			} else
+				colorTableIndex = CQUAD * stream->readByte();
+
+			while (numBlocks--) {
+				colorFlags = stream->readUint32BE();
+
+				// flag mask actually acts as a bit shift count here
+				byte flagMask = 30;
+				blockPtr = rowPtr + pixelPtr;
+
+				for (byte y = 0; y < 4; y++) {
+					for (byte x = 0; x < 4; x++) {
+						pixel = colorTableIndex + ((colorFlags >> flagMask) & 0x03);
+						flagMask -= 2;
+						pixels[blockPtr++] = _colorQuads[pixel];
+					}
+					blockPtr += rowInc;
+				}
+				ADVANCE_BLOCK();
+			}
+			break;
+
+		// 8-color block encoding
+		case 0xC0:
+		case 0xD0:
+			numBlocks = (opcode & 0x0F) + 1;
+
+			// figure out which color octet to use to paint the 8-color block
+			if ((opcode & 0xF0) == 0xC0) {
+				// fetch the next 8 colors from bytestream and store in next
+				// available entry in the color octet table
+				for (byte i = 0; i < COCTET; i++) {
+					pixel = stream->readByte();
+					colorTableIndex = COCTET * colorOctetIndex + i;
+					_colorOctets[colorTableIndex] = pixel;
+				}
+
+				// this is the base index to use for this block
+				colorTableIndex = COCTET * colorOctetIndex;
+				colorOctetIndex++;
+
+				// wraparound
+				if (colorOctetIndex == COLORS_PER_TABLE)
+					colorOctetIndex = 0;
+			} else
+				colorTableIndex = COCTET * stream->readByte();
+
+			while (numBlocks--) {
+				/*
+				  For this input of 6 hex bytes:
+				    01 23 45 67 89 AB
+				  Mangle it to this output:
+				    flags_a = xx012456, flags_b = xx89A37B
+				*/
+
+				// build the color flags
+				byte flagData[6];
+				stream->read(flagData, 6);
+
+				colorFlagsA = ((READ_BE_UINT16(flagData) & 0xFFF0) << 8) | (READ_BE_UINT16(flagData + 2) >> 4);
+				colorFlagsB = ((READ_BE_UINT16(flagData + 4) & 0xFFF0) << 8) | ((flagData[1] & 0xF) << 8) |
+								((flagData[3] & 0xF) << 4) | (flagData[5] & 0xf);
+
+				colorFlags = colorFlagsA;
+
+				// flag mask actually acts as a bit shift count here
+				byte flagMask = 21;
+				blockPtr = rowPtr + pixelPtr;
+				for (byte y = 0; y < 4; y++) {
+					// reload flags at third row (iteration y == 2)
+					if (y == 2) {
+						colorFlags = colorFlagsB;
+						flagMask = 21;
+					}
+
+					for (byte x = 0; x < 4; x++) {
+						pixel = colorTableIndex + ((colorFlags >> flagMask) & 0x07);
+						flagMask -= 3;
+						pixels[blockPtr++] = _colorOctets[pixel];
+					}
+
+					blockPtr += rowInc;
+				}
+				ADVANCE_BLOCK();
+			}
+			break;
+
+		// 16-color block encoding (every pixel is a different color)
+		case 0xE0:
+			numBlocks = (opcode & 0x0F) + 1;
+
+			while (numBlocks--) {
+				blockPtr = rowPtr + pixelPtr;
+				for (byte y = 0; y < 4; y++) {
+					for (byte x = 0; x < 4; x++)
+						pixels[blockPtr++] = stream->readByte();
+
+					blockPtr += rowInc;
+				}
+				ADVANCE_BLOCK();
+			}
+			break;
+
+		case 0xF0:
+			warning("0xF0 opcode seen in SMC chunk (contact the developers)");
+			break;
+		}
+	}
+
+	return _surface;
+}
+
+} // End of namespace Graphics

Copied: scummvm/trunk/graphics/video/codecs/smc.h (from rev 49161, scummvm/trunk/engines/mohawk/video/smc.h)
===================================================================
--- scummvm/trunk/graphics/video/codecs/smc.h	                        (rev 0)
+++ scummvm/trunk/graphics/video/codecs/smc.h	2010-05-23 18:33:55 UTC (rev 49165)
@@ -0,0 +1,59 @@
+/* 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_VIDEO_SMC_H
+#define GRAPHICS_VIDEO_SMC_H
+
+#include "graphics/video/codecs/codec.h"
+
+namespace Graphics {
+
+enum {
+	CPAIR = 2,
+	CQUAD = 4,
+	COCTET = 8,
+	COLORS_PER_TABLE = 256
+};
+
+class SMCDecoder : public Codec {
+public:
+	SMCDecoder(uint16 width, uint16 height);
+	~SMCDecoder() { delete _surface; }
+
+	Surface *decodeImage(Common::SeekableReadStream *stream);
+	PixelFormat getPixelFormat() const { return PixelFormat::createFormatCLUT8(); }
+
+private:
+	Surface *_surface;
+
+	// SMC color tables
+	byte _colorPairs[COLORS_PER_TABLE * CPAIR];
+	byte _colorQuads[COLORS_PER_TABLE * CQUAD];
+	byte _colorOctets[COLORS_PER_TABLE * COCTET];
+};
+
+} // End of namespace Graphics
+
+#endif

Copied: scummvm/trunk/graphics/video/qt_decoder.cpp (from rev 49161, scummvm/trunk/engines/mohawk/video/qt_player.cpp)
===================================================================
--- scummvm/trunk/graphics/video/qt_decoder.cpp	                        (rev 0)
+++ scummvm/trunk/graphics/video/qt_decoder.cpp	2010-05-23 18:33:55 UTC (rev 49165)
@@ -0,0 +1,1279 @@
+/* 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$
+ *
+ */
+
+//
+// Heavily based on ffmpeg code.
+//
+// Copyright (c) 2001 Fabrice Bellard.
+// First version by Francois Revol revol at free.fr
+// Seek function by Gael Chardon gael.dev at 4now.net
+//
+
+#include "graphics/video/qt_decoder.h"
+
+#include "common/debug.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/zlib.h"
+
+// Audio codecs
+#include "sound/decoders/adpcm.h"
+#include "sound/decoders/raw.h"
+#include "sound/decoders/qdm2.h"
+
+// Video codecs
+#include "graphics/video/codecs/cinepak.h"
+#include "graphics/video/codecs/mjpeg.h"
+#include "graphics/video/codecs/qtrle.h"
+#include "graphics/video/codecs/rpza.h"
+#include "graphics/video/codecs/smc.h"
+
+namespace Graphics {
+
+////////////////////////////////////////////
+// QuickTimeDecoder
+////////////////////////////////////////////
+
+QuickTimeDecoder::QuickTimeDecoder() : VideoDecoder() {
+	_audStream = NULL;
+	_beginOffset = 0;
+	_videoCodec = NULL;
+	_curFrame = -1;
+	_startTime = _nextFrameStartTime = 0;
+	_audHandle = Audio::SoundHandle();
+	_numStreams = 0;
+	_fd = 0;
+	_scaledSurface = 0;
+	_dirtyPalette = false;
+}
+
+QuickTimeDecoder::~QuickTimeDecoder() {
+	close();
+}
+
+uint16 QuickTimeDecoder::getWidth() const {
+	if (_videoStreamIndex < 0)
+		return 0;
+
+	return _streams[_videoStreamIndex]->width / getScaleMode();
+}
+
+uint16 QuickTimeDecoder::getHeight() const {
+	if (_videoStreamIndex < 0)
+		return 0;
+
+	return _streams[_videoStreamIndex]->height / getScaleMode();
+}
+
+uint32 QuickTimeDecoder::getFrameCount() const {
+	if (_videoStreamIndex < 0)
+		return 0;
+
+	return _streams[_videoStreamIndex]->nb_frames;
+}
+
+byte QuickTimeDecoder::getBitsPerPixel() {
+	if (_videoStreamIndex < 0)
+		return 0;
+
+	return _streams[_videoStreamIndex]->bits_per_sample & 0x1F;
+}
+
+uint32 QuickTimeDecoder::getCodecTag() {
+	if (_videoStreamIndex < 0)
+		return 0;
+
+	return _streams[_videoStreamIndex]->codec_tag;
+}
+
+ScaleMode QuickTimeDecoder::getScaleMode() const {
+	if (_videoStreamIndex < 0)
+		return kScaleNormal;
+
+	return (ScaleMode)(_scaleMode * _streams[_videoStreamIndex]->scaleMode);
+}
+
+uint32 QuickTimeDecoder::getFrameDuration() {
+	if (_videoStreamIndex < 0)
+		return 0;
+
+	uint32 curFrameIndex = 0;
+	for (int32 i = 0; i < _streams[_videoStreamIndex]->stts_count; i++) {
+		curFrameIndex += _streams[_videoStreamIndex]->stts_data[i].count;
+		if ((uint32)_curFrame < curFrameIndex) {
+			// Ok, now we have what duration this frame has.
+			return _streams[_videoStreamIndex]->stts_data[i].duration;
+		}
+	}
+
+	// This should never occur
+	error ("Cannot find duration for frame %d", _curFrame);
+	return 0;
+}
+
+PixelFormat QuickTimeDecoder::getPixelFormat() const {
+	if (!_videoCodec)
+		return PixelFormat::createFormatCLUT8();
+
+	return _videoCodec->getPixelFormat();
+}
+
+void QuickTimeDecoder::rewind() {
+	delete _videoCodec; _videoCodec = NULL;
+	_curFrame = -1;
+	_startTime = _nextFrameStartTime = 0;
+
+	// Restart the audio too
+	stopAudio();
+	if (_audioStreamIndex >= 0) {
+		_curAudioChunk = 0;
+		_audStream = Audio::makeQueuingAudioStream(_streams[_audioStreamIndex]->sample_rate, _streams[_audioStreamIndex]->channels == 2);
+	}
+	startAudio();
+}
+
+Codec *QuickTimeDecoder::createCodec(uint32 codecTag, byte bitsPerPixel) {
+	if (codecTag == MKID_BE('cvid')) {
+		// 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();
+	} else if (codecTag == MKID_BE('rpza')) {
+		// Apple Video ("Road Pizza"): Used by some Myst videos.
+		return new RPZADecoder(getWidth(), getHeight());
+	} else if (codecTag == MKID_BE('rle ')) {
+		// QuickTime RLE: Used by some Myst ME videos.
+		return new QTRLEDecoder(getWidth(), getHeight(), bitsPerPixel);
+	} else if (codecTag == MKID_BE('smc ')) {
+		// Apple SMC: Used by some Myst videos.
+		return new SMCDecoder(getWidth(), getHeight());
+	} else if (codecTag == MKID_BE('SVQ1')) {
+		// Sorenson Video 1: Used by some Myst ME videos.
+		warning ("Sorenson Video 1 not yet supported");
+	} else if (codecTag == MKID_BE('SVQ3')) {
+		// Sorenson Video 3: Used by some Myst ME videos.
+		warning ("Sorenson Video 3 not yet supported");
+	} else if (codecTag == MKID_BE('jpeg')) {
+		// Motion JPEG: Used by some Myst ME 10th Anniversary videos.
+		return new JPEGDecoder();
+	} else if (codecTag == MKID_BE('QkBk')) {
+		// CDToons: Used by most of the Broderbund games. This is an unknown format so far.
+		warning ("CDToons not yet supported");
+	} else {
+		warning ("Unsupported codec \'%s\'", tag2str(codecTag));
+	}
+
+	return NULL;
+}
+
+void QuickTimeDecoder::startAudio() {
+	if (_audStream) // No audio/audio not supported
+		g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audHandle, _audStream);
+}
+
+void QuickTimeDecoder::stopAudio() {
+	if (_audStream) {
+		g_system->getMixer()->stopHandle(_audHandle);
+		_audStream = NULL; // the mixer automatically frees the stream
+	}
+}
+
+void QuickTimeDecoder::pauseVideoIntern(bool pause) {
+	if (_audStream)
+		g_system->getMixer()->pauseHandle(_audHandle, pause);		
+}
+
+Surface *QuickTimeDecoder::decodeNextFrame() {
+	if (!_videoCodec || _curFrame >= (int32)getFrameCount() - 1)
+		return NULL;
+
+	if (_startTime == 0)
+		_startTime = g_system->getMillis();
+
+	_curFrame++;
+	_nextFrameStartTime += getFrameDuration();
+
+	Common::SeekableReadStream *frameData = getNextFramePacket();
+
+	if (frameData) {
+		Surface *frame = _videoCodec->decodeImage(frameData);
+		delete frameData;
+		return scaleSurface(frame);
+	}
+
+	return NULL;
+}
+
+Surface *QuickTimeDecoder::scaleSurface(Surface *frame) {
+	if (getScaleMode() == kScaleNormal)
+		return frame;
+
+	assert(_scaledSurface);
+
+	for (uint32 j = 0; j < _scaledSurface->h; j++)
+		for (uint32 k = 0; k < _scaledSurface->w; k++)
+			memcpy(_scaledSurface->getBasePtr(k, j), frame->getBasePtr(k * getScaleMode(), j * getScaleMode()), frame->bytesPerPixel);
+
+	return _scaledSurface;
+}
+
+bool QuickTimeDecoder::endOfVideo() const {
+	return (!_audStream || _audStream->endOfData()) && (!_videoCodec || _curFrame >= (int32)getFrameCount() - 1);
+}
+
+bool QuickTimeDecoder::needsUpdate() const {
+	return !endOfVideo() && getTimeToNextFrame() == 0;
+}
+
+uint32 QuickTimeDecoder::getElapsedTime() const {
+	if (_audStream)
+		return g_system->getMixer()->getSoundElapsedTime(_audHandle);
+
+	return g_system->getMillis() - _startTime;
+}
+
+uint32 QuickTimeDecoder::getTimeToNextFrame() const {
+	if (endOfVideo() || _curFrame < 0)
+		return 0;
+
+	// Convert from the Sega FILM base to 1000
+	uint32 nextFrameStartTime = _nextFrameStartTime * 1000 / _streams[_videoStreamIndex]->time_scale;
+	uint32 elapsedTime = getElapsedTime();
+
+	if (nextFrameStartTime <= elapsedTime)
+		return 0;
+
+	return nextFrameStartTime - elapsedTime;
+}
+
+bool QuickTimeDecoder::load(Common::SeekableReadStream &stream) {
+	_fd = &stream;
+	_foundMOOV = _foundMDAT = false;
+	_numStreams = 0;
+	_partial = 0;
+	_videoStreamIndex = _audioStreamIndex = -1;
+	_startTime = 0;
+
+	initParseTable();
+
+	MOVatom atom = { 0, 0, 0xffffffff };
+
+	if (readDefault(atom) < 0 || (!_foundMOOV && !_foundMDAT))
+		return false;
+
+	debug(0, "on_parse_exit_offset=%d", _fd->pos());
+
+	// some cleanup : make sure we are on the mdat atom
+	if((uint32)_fd->pos() != _mdatOffset)
+		_fd->seek(_mdatOffset, SEEK_SET);
+
+	_next_chunk_offset = _mdatOffset; // initialise reading
+
+	for (uint32 i = 0; i < _numStreams;) {
+		if (_streams[i]->codec_type == CODEC_TYPE_MOV_OTHER) {// not audio, not video, delete
+			delete _streams[i];
+			for (uint32 j = i + 1; j < _numStreams; j++)
+				_streams[j - 1] = _streams[j];
+			_numStreams--;
+		} else
+			i++;
+	}
+
+	for (uint32 i = 0; i < _numStreams; i++) {
+		MOVStreamContext *sc = _streams[i];
+
+		if(!sc->time_rate)
+			sc->time_rate = 1;
+
+		if(!sc->time_scale)
+			sc->time_scale = _timeScale;
+
+		//av_set_pts_info(s->streams[i], 64, sc->time_rate, sc->time_scale);
+
+		sc->duration /= sc->time_rate;
+
+		sc->ffindex = i;
+		sc->is_ff_stream = 1;
+
+		if (sc->codec_type == CODEC_TYPE_VIDEO && _videoStreamIndex < 0)
+			_videoStreamIndex = i;
+		else if (sc->codec_type == CODEC_TYPE_AUDIO && _audioStreamIndex < 0)
+			_audioStreamIndex = i;
+	}
+
+	if (_audioStreamIndex >= 0 && checkAudioCodecSupport(_streams[_audioStreamIndex]->codec_tag)) {
+		_audStream = Audio::makeQueuingAudioStream(_streams[_audioStreamIndex]->sample_rate, _streams[_audioStreamIndex]->channels == 2);
+		_curAudioChunk = 0;
+
+		// Make sure the bits per sample transfers to the sample size
+		if (_streams[_audioStreamIndex]->codec_tag == MKID_BE('raw ') || _streams[_audioStreamIndex]->codec_tag == MKID_BE('twos'))
+			_streams[_audioStreamIndex]->sample_size = (_streams[_audioStreamIndex]->bits_per_sample / 8) * _streams[_audioStreamIndex]->channels;
+
+		startAudio();
+	}
+
+	if (_videoStreamIndex >= 0) {
+		_videoCodec = createCodec(getCodecTag(), getBitsPerPixel());
+
+		if (getScaleMode() != kScaleNormal) {
+			// We have to initialize the scaled surface
+			_scaledSurface = new Surface();
+			_scaledSurface->create(getWidth(), getHeight(), getPixelFormat().bytesPerPixel);
+		}
+	}
+
+	return true;
+}
+
+void QuickTimeDecoder::initParseTable() {
+	static const ParseTable p[] = {
+		{ MKID_BE('dinf'), &QuickTimeDecoder::readDefault },
+		{ MKID_BE('dref'), &QuickTimeDecoder::readLeaf },
+		{ MKID_BE('edts'), &QuickTimeDecoder::readDefault },
+		{ MKID_BE('elst'), &QuickTimeDecoder::readELST },
+		{ MKID_BE('hdlr'), &QuickTimeDecoder::readHDLR },
+		{ MKID_BE('mdat'), &QuickTimeDecoder::readMDAT },
+		{ MKID_BE('mdhd'), &QuickTimeDecoder::readMDHD },
+		{ MKID_BE('mdia'), &QuickTimeDecoder::readDefault },
+		{ MKID_BE('minf'), &QuickTimeDecoder::readDefault },
+		{ MKID_BE('moov'), &QuickTimeDecoder::readMOOV },
+		{ MKID_BE('mvhd'), &QuickTimeDecoder::readMVHD },
+		{ MKID_BE('smhd'), &QuickTimeDecoder::readLeaf },
+		{ MKID_BE('stbl'), &QuickTimeDecoder::readDefault },
+		{ MKID_BE('stco'), &QuickTimeDecoder::readSTCO },
+		{ MKID_BE('stsc'), &QuickTimeDecoder::readSTSC },
+		{ MKID_BE('stsd'), &QuickTimeDecoder::readSTSD },
+		{ MKID_BE('stss'), &QuickTimeDecoder::readSTSS },
+		{ MKID_BE('stsz'), &QuickTimeDecoder::readSTSZ },
+		{ MKID_BE('stts'), &QuickTimeDecoder::readSTTS },
+		{ MKID_BE('tkhd'), &QuickTimeDecoder::readTKHD },
+		{ MKID_BE('trak'), &QuickTimeDecoder::readTRAK },
+		{ MKID_BE('udta'), &QuickTimeDecoder::readLeaf },
+		{ MKID_BE('vmhd'), &QuickTimeDecoder::readLeaf },
+		{ MKID_BE('cmov'), &QuickTimeDecoder::readCMOV },
+		{ MKID_BE('wave'), &QuickTimeDecoder::readWAVE },
+		{ 0, 0 }
+	};
+
+	_parseTable = p;
+}
+
+int QuickTimeDecoder::readDefault(MOVatom atom) {
+	uint32 total_size = 0;
+	MOVatom a;
+	int err = 0;
+
+	a.offset = atom.offset;
+
+	while(((total_size + 8) < atom.size) && !_fd->eos() && !err) {
+		a.size = atom.size;
+		a.type = 0;
+
+		if (atom.size >= 8) {
+			a.size = _fd->readUint32BE();
+			a.type = _fd->readUint32BE();
+		}
+
+		total_size += 8;
+		a.offset += 8;
+		debug(4, "type: %08x  %.4s  sz: %x %x %x", a.type, tag2str(a.type), a.size, atom.size, total_size);
+
+		if (a.size == 1) { // 64 bit extended size
+			warning("64 bit extended size is not supported in QuickTime");
+			return -1;
+		}
+
+		if (a.size == 0) {
+			a.size = atom.size - total_size;
+			if (a.size <= 8)
+				break;
+		}
+
+		uint32 i = 0;
+
+		for (; _parseTable[i].type != 0 && _parseTable[i].type != a.type; i++)
+			// empty;
+
+		if (a.size < 8)
+			break;
+
+		a.size -= 8;
+
+		if (_parseTable[i].type == 0) { // skip leaf atoms data
+			debug(0, ">>> Skipped [%s]", tag2str(a.type));
+
+			_fd->seek(a.size, SEEK_CUR);
+		} else {
+			uint32 start_pos = _fd->pos();
+			err = (this->*_parseTable[i].func)(a);
+
+			uint32 left = a.size - _fd->pos() + start_pos;
+
+			if (left > 0) // skip garbage at atom end
+				_fd->seek(left, SEEK_CUR);
+		}
+
+		a.offset += a.size;
+		total_size += a.size;
+	}
+
+	if (!err && total_size < atom.size)
+		_fd->seek(atom.size - total_size, SEEK_SET);
+
+	return err;
+}
+
+int QuickTimeDecoder::readLeaf(MOVatom atom) {
+	if (atom.size > 1)
+		_fd->seek(atom.size, SEEK_SET);
+
+	return 0;
+}
+
+int QuickTimeDecoder::readMOOV(MOVatom atom) {
+	if (readDefault(atom) < 0)
+		return -1;
+
+	// we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat'
+	// so we don't parse the whole file if over a network
+	_foundMOOV = true;
+
+	if(_foundMDAT)
+		return 1; // found both, just go
+
+	return 0; // now go for mdat
+}
+
+int QuickTimeDecoder::readCMOV(MOVatom atom) {
+#ifdef USE_ZLIB
+	// Read in the dcom atom
+	_fd->readUint32BE();
+	if (_fd->readUint32BE() != MKID_BE('dcom'))
+		return -1;
+	if (_fd->readUint32BE() != MKID_BE('zlib')) {
+		warning("Unknown cmov compression type");
+		return -1;
+	}
+
+	// Read in the cmvd atom
+	uint32 compressedSize = _fd->readUint32BE() - 12;
+	if (_fd->readUint32BE() != MKID_BE('cmvd'))
+		return -1;
+	uint32 uncompressedSize = _fd->readUint32BE();
+
+	// Read in data
+	byte *compressedData = (byte *)malloc(compressedSize);
+	_fd->read(compressedData, compressedSize);
+
+	// Create uncompressed stream
+	byte *uncompressedData = (byte *)malloc(uncompressedSize);
+
+	// Uncompress the data
+	unsigned long dstLen = uncompressedSize;
+	if (!Common::uncompress(uncompressedData, &dstLen, compressedData, compressedSize)) {
+		warning ("Could not uncompress cmov chunk");
+		return -1;
+	}
+
+	// Load data into a new MemoryReadStream and assign _fd to be that
+	Common::SeekableReadStream *oldStream = _fd;
+	_fd = new Common::MemoryReadStream(uncompressedData, uncompressedSize, DisposeAfterUse::YES);
+
+	// Read the contents of the uncompressed data
+	MOVatom a = { MKID_BE('moov'), 0, uncompressedSize };
+	int err = readDefault(a);
+
+	// Assign the file handle back to the original handle
+	free(compressedData);
+	delete _fd;
+	_fd = oldStream;
+
+	return err;
+#else
+	warning ("zlib not found, cannot read QuickTime cmov atom");
+	return -1;
+#endif
+}
+
+int QuickTimeDecoder::readMVHD(MOVatom atom) {
+	byte version = _fd->readByte(); // version
+	_fd->readByte(); _fd->readByte(); _fd->readByte(); // flags
+
+	if (version == 1) {
+		warning("QuickTime version 1");
+		_fd->readUint32BE(); _fd->readUint32BE();
+		_fd->readUint32BE(); _fd->readUint32BE();
+	} else {
+		_fd->readUint32BE(); // creation time
+		_fd->readUint32BE(); // modification time
+	}
+
+	_timeScale = _fd->readUint32BE(); // time scale
+	debug(0, "time scale = %i\n", _timeScale);
+
+	// duration
+	_duration = (version == 1) ? (_fd->readUint32BE(), _fd->readUint32BE()) : _fd->readUint32BE();
+	_fd->readUint32BE(); // preferred scale
+
+	_fd->readUint16BE(); // preferred volume
+
+	_fd->seek(10, SEEK_CUR); // reserved
+
+	// We only need two values from the movie display matrix. Most of the values are just
+	// skipped. xMod and yMod are 16:16 fixed point numbers, the last part of the 3x3 matrix
+	// is 2:30.
+	uint32 xMod = _fd->readUint32BE();
+	_fd->skip(12);
+	uint32 yMod = _fd->readUint32BE();
+	_fd->skip(16);
+
+	if (xMod != yMod)
+		error("X and Y resolution modifiers differ");
+
+	if (xMod == 0x8000)
+		_scaleMode = kScaleHalf;
+	else if (xMod == 0x4000)
+		_scaleMode = kScaleQuarter;
+	else
+		_scaleMode = kScaleNormal;
+
+	debug(1, "readMVHD(): scaleMode = %d", (int)_scaleMode);
+
+	_fd->readUint32BE(); // preview time
+	_fd->readUint32BE(); // preview duration
+	_fd->readUint32BE(); // poster time
+	_fd->readUint32BE(); // selection time
+	_fd->readUint32BE(); // selection duration
+	_fd->readUint32BE(); // current time
+	_fd->readUint32BE(); // next track ID
+
+	return 0;
+}
+
+int QuickTimeDecoder::readTRAK(MOVatom atom) {
+	MOVStreamContext *sc = new MOVStreamContext();
+
+	if (!sc)
+		return -1;
+
+	sc->sample_to_chunk_index = -1;

@@ Diff output truncated at 100000 characters. @@

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