[Scummvm-cvs-logs] SF.net SVN: scummvm:[39571] scummvm/trunk/engines/parallaction

peres001 at users.sourceforge.net peres001 at users.sourceforge.net
Fri Mar 20 21:37:06 CET 2009


Revision: 39571
          http://scummvm.svn.sourceforge.net/scummvm/?rev=39571&view=rev
Author:   peres001
Date:     2009-03-20 20:37:06 +0000 (Fri, 20 Mar 2009)

Log Message:
-----------
Added more flexible IFF parser and ILBM decoder.

Modified Paths:
--------------
    scummvm/trunk/engines/parallaction/module.mk

Added Paths:
-----------
    scummvm/trunk/engines/parallaction/iff.cpp
    scummvm/trunk/engines/parallaction/iff.h

Added: scummvm/trunk/engines/parallaction/iff.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/iff.cpp	                        (rev 0)
+++ scummvm/trunk/engines/parallaction/iff.cpp	2009-03-20 20:37:06 UTC (rev 39571)
@@ -0,0 +1,261 @@
+/* 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/iff_container.h"
+#include "common/stream.h"
+#include "common/util.h"
+#include "parallaction/iff.h"
+
+namespace Parallaction {
+
+
+void IFFParser::setInputStream(Common::SeekableReadStream *stream) {
+	destroy();
+
+	assert(stream);
+	_stream = stream;
+	_startOffset = 0;
+	_endOffset = _stream->size();
+}
+
+void IFFParser::destroy() {
+	_stream = 0;
+	_startOffset = _endOffset = 0;
+}
+
+uint32 IFFParser::getFORMBlockSize() {
+	uint32 oldOffset = _stream->pos();
+
+	uint32 data = _stream->readUint32BE();
+
+	if (data != ID_FORM) {
+		_stream->seek(oldOffset);
+		return (uint32)-1;
+	}
+
+	data = _stream->readUint32BE();
+	return data;
+}
+
+uint32 IFFParser::moveToIFFBlock(Common::IFF_ID chunkName) {
+	uint32 size = (uint32)-1;
+
+	_stream->seek(_startOffset + 0x0C);
+
+	while ((uint)_stream->pos() < _endOffset) {
+		uint32 chunk = _stream->readUint32BE();
+		uint32 size_temp = _stream->readUint32BE();
+
+		if (chunk != chunkName) {
+			_stream->seek((size_temp + 1) & (~1), SEEK_CUR);
+			assert((uint)_stream->pos() <= _endOffset);
+		} else {
+			size = size_temp;
+			break;
+		}
+	}
+
+	return size;
+}
+
+uint32 IFFParser::getIFFBlockSize(Common::IFF_ID chunkName) {
+	uint32 size = moveToIFFBlock(chunkName);
+	return size;
+}
+
+bool IFFParser::loadIFFBlock(Common::IFF_ID chunkName, void *loadTo, uint32 ptrSize) {
+	uint32 chunkSize = moveToIFFBlock(chunkName);
+
+	if (chunkSize == (uint32)-1) {
+		return false;
+	}
+
+	uint32 loadSize = 0;
+	loadSize = MIN(ptrSize, chunkSize);
+	_stream->read(loadTo, loadSize);
+	return true;
+}
+
+Common::SeekableReadStream *IFFParser::getIFFBlockStream(Common::IFF_ID chunkName) {
+	uint32 chunkSize = moveToIFFBlock(chunkName);
+
+	if (chunkSize == (uint32)-1) {
+		return 0;
+	}
+
+	uint32 pos = _stream->pos();
+	return new Common::SeekableSubReadStream(_stream, pos, pos + chunkSize, false);
+}
+
+
+// ILBM decoder implementation
+
+ILBMDecoder::ILBMDecoder(Common::SeekableReadStream *in, bool disposeStream) : _in(in), _hasHeader(false), _bodySize((uint32)-1), _paletteSize((uint32)-1) {
+	assert(in);
+	_parser.setInputStream(in);
+
+	_hasHeader = _parser.loadIFFBlock(ID_BMHD, &_header, sizeof(_header));
+	if (!_hasHeader) {
+		return;
+	}
+
+	_header.width = TO_BE_16(_header.width);
+	_header.height = TO_BE_16(_header.height);
+
+	_paletteSize = _parser.getIFFBlockSize(ID_CMAP);
+	_bodySize = _parser.getIFFBlockSize(ID_BODY);
+}
+
+
+ILBMDecoder::~ILBMDecoder() {
+	if (_disposeStream) {
+		delete _in;
+	}
+}
+
+uint32 ILBMDecoder::getWidth() {
+	assert(_hasHeader);
+	return _header.width;
+}
+
+uint32 ILBMDecoder::getHeight() {
+	assert(_hasHeader);
+	return _header.height;
+}
+
+uint32 ILBMDecoder::getNumColors() {
+	assert(_hasHeader);
+	return (1 << _header.depth);
+}
+
+byte *ILBMDecoder::getPalette() {
+	assert(_paletteSize != (uint32)-1);
+	byte *palette = new byte[_paletteSize];
+	assert(palette);
+	_parser.loadIFFBlock(ID_CMAP, palette, _paletteSize);
+	return palette;
+}
+
+byte *ILBMDecoder::getBitmap(uint32 numPlanes, bool packPlanes) {
+	assert(_bodySize != (uint32)-1);
+	assert(numPlanes == 2 || numPlanes == 4 || numPlanes == 8);
+
+	numPlanes = MIN(numPlanes, (uint32)_header.depth);
+	if (numPlanes == 8) {
+		packPlanes = false;
+	}
+
+	uint32 bitmapSize = _header.width * _header.height;
+	uint32 bitmapWidth = _header.width;
+	if (packPlanes) {
+		bitmapSize /= (8 / numPlanes);
+		bitmapWidth /= (8 / numPlanes);
+	}
+
+	Common::SeekableReadStream *bodyStream = _parser.getIFFBlockStream(ID_BODY);
+	assert(bodyStream);
+
+	byte *bitmap = new byte[bitmapSize];
+	assert(bitmap);
+	memset(bitmap, 0, bitmapSize);
+
+	switch (_header.pack) {
+	case 1: {	// PackBits compressed bitmap
+		Graphics::PackBitsReadStream stream(*bodyStream);
+
+		byte *out = bitmap;
+
+		// setup a buffer to hold enough data to build a line in the output
+		uint32 scanWidth = (_header.width + 7) >> 3;
+		byte *scanBuffer = (byte*)malloc(scanWidth * _header.depth);
+
+		for (uint i = 0; i < _header.height; ++i) {
+			byte *s = scanBuffer;
+			for (uint32 j = 0; j < _header.depth; ++j) {
+				stream.read(s, scanWidth);
+				s += scanWidth;
+			}
+
+			planarToChunky(out, bitmapWidth, scanBuffer, scanWidth, numPlanes, packPlanes);
+			out += bitmapWidth;
+		}
+
+		free(scanBuffer);
+		break;
+	}
+	default:
+		error("only RLE compressed ILBM files are supported");
+		break;
+	}
+
+	delete bodyStream;
+
+	return bitmap;
+}
+
+
+void ILBMDecoder::planarToChunky(byte *out, uint32 width, byte *in, uint32 planeWidth, uint32 nPlanes, bool packPlanes) {
+	byte pix, ofs, bit;
+	byte *s;
+
+	uint32 pixels = width;
+	if (packPlanes) {
+		pixels *= (8 / nPlanes);
+	}
+
+	for (uint32 x = 0; x < pixels; ++x) {
+
+		pix = 0;
+		ofs = x >> 3;
+		bit = 0x80 >> (x & 7);
+
+		// first build a pixel by scanning all the usable planes in the input
+		s = in;
+		for (uint32 plane = 0; plane < nPlanes; ++plane) {
+			if (s[ofs] & bit) {
+				pix |= (1 << plane);
+			}
+			s += planeWidth;
+		}
+
+
+		// then output the pixel according to the requested packing
+		if (!packPlanes) {
+			out[x] = pix;
+		} else
+		if (nPlanes == 2) {
+			out[x/4] |= (pix << ((x & 3) << 1));
+		} else
+		if (nPlanes == 4) {
+			out[x/2] |= (pix << ((x & 1) << 2));
+		}
+	}
+
+}
+
+
+} // end of namespace Kyra
+


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

Added: scummvm/trunk/engines/parallaction/iff.h
===================================================================
--- scummvm/trunk/engines/parallaction/iff.h	                        (rev 0)
+++ scummvm/trunk/engines/parallaction/iff.h	2009-03-20 20:37:06 UTC (rev 39571)
@@ -0,0 +1,97 @@
+/* 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 PARALLACTION_IFF_H
+#define PARALLACTION_IFF_H
+
+#include "common/stream.h"
+#include "common/iff_container.h"		// for IFF chunk names
+#include "graphics/iff.h"				// for BMHD
+
+// this IFF parser code is courtesy of the Kyra engine team ;)
+
+namespace Parallaction {
+
+class IFFParser {
+public:
+	IFFParser() : _stream(0), _startOffset(0), _endOffset(0) {}
+	IFFParser(Common::SeekableReadStream *stream) : _stream(0), _startOffset(0), _endOffset(0) {
+		setInputStream(stream);
+	}
+	~IFFParser() { destroy(); }
+
+	void setInputStream(Common::SeekableReadStream *stream);
+
+	operator bool() const { return (_startOffset != _endOffset) && _stream; }
+
+	uint32 getFORMBlockSize();
+	uint32 getIFFBlockSize(Common::IFF_ID chunk);
+	bool loadIFFBlock(Common::IFF_ID chunk, void *loadTo, uint32 ptrSize);
+	Common::SeekableReadStream *getIFFBlockStream(Common::IFF_ID chunkName);
+private:
+	void destroy();
+	uint32 moveToIFFBlock(Common::IFF_ID chunkName);
+
+	Common::SeekableReadStream *_stream;
+	uint32 _startOffset;
+	uint32 _endOffset;
+};
+
+
+
+
+class ILBMDecoder {
+	Common::SeekableReadStream *_in;
+	IFFParser 		_parser;
+	Graphics::BMHD 	_header;
+	bool	_hasHeader;
+	uint32	_bodySize;
+	uint32	_paletteSize;
+	bool _disposeStream;
+
+	void planarToChunky(byte *out, uint32 width, byte *in, uint32 planeWidth, uint32 nPlanes, bool packPlanes);
+
+public:
+	ILBMDecoder(Common::SeekableReadStream *input, bool disposeStream = false);
+
+	virtual ~ILBMDecoder();
+
+	uint32 getWidth();
+	uint32 getHeight();
+	uint32 getNumColors();
+	byte *getPalette();
+
+	byte *getBitmap(uint32 numPlanes, bool packPlanes);
+	byte *getBitmap() {
+		assert(_hasHeader);
+		return getBitmap(_header.depth, false);
+	}
+};
+
+
+}
+
+#endif
+


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

Modified: scummvm/trunk/engines/parallaction/module.mk
===================================================================
--- scummvm/trunk/engines/parallaction/module.mk	2009-03-20 19:02:32 UTC (rev 39570)
+++ scummvm/trunk/engines/parallaction/module.mk	2009-03-20 20:37:06 UTC (rev 39571)
@@ -18,6 +18,7 @@
 	gui.o \
 	gui_br.o \
 	gui_ns.o \
+	iff.o \
 	input.o \
 	inventory.o \
 	objects.o \


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