[Scummvm-cvs-logs] scummvm master -> c0babb010a7f803e54f3021e9560d77baf69fdb8

bluegr bluegr at gmail.com
Sun Sep 16 23:07:14 CEST 2012


This automated email contains information about 7 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
ccccb392b5 GRAPHICS: Add a common PCX image decoder
d182fe0221 QUEEN: Switch to the common PCX decoder
617545cb5f TUCKER: Switch to the common PCX decoder
28733463fa DREAMWEB: Switch to the common PCX decoder
fb6a5a140d HUGO: Switch to the common PCX decoder
ef671f20b1 HUGO: Use surface width instead of its pitch when copying to raw memory blobs
c0babb010a Merge pull request #278 from bluegr/pcxdecoder


Commit: ccccb392b55ee64130ac87aa5737321a943ee628
    https://github.com/scummvm/scummvm/commit/ccccb392b55ee64130ac87aa5737321a943ee628
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2012-09-12T15:49:29-07:00

Commit Message:
GRAPHICS: Add a common PCX image decoder

Changed paths:
  A graphics/decoders/pcx.cpp
  A graphics/decoders/pcx.h
    graphics/module.mk



diff --git a/graphics/decoders/pcx.cpp b/graphics/decoders/pcx.cpp
new file mode 100644
index 0000000..f5c1c24
--- /dev/null
+++ b/graphics/decoders/pcx.cpp
@@ -0,0 +1,213 @@
+/* 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.
+ */
+
+#include "common/stream.h"
+#include "common/textconsole.h"
+
+#include "graphics/pixelformat.h"
+#include "graphics/surface.h"
+#include "graphics/decoders/pcx.h"
+
+/**
+ * Based on the PCX specs:
+ * http://www.fileformat.info/format/pcx/spec/a10e75307b3a4cc49c3bbe6db4c41fa2/view.htm
+ * and the PCX decoder of FFmpeg (libavcodec/pcx.c):
+ * http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavcodec/pcx.c
+ */
+
+namespace Graphics {
+
+PCXDecoder::PCXDecoder() {
+	_surface = 0;
+	_palette = 0;
+	_paletteColorCount = 0;
+}
+
+PCXDecoder::~PCXDecoder() {
+	destroy();
+}
+
+void PCXDecoder::destroy() {
+	if (_surface) {
+		_surface->free();
+		delete _surface;
+		_surface = 0;
+	}
+
+	delete[] _palette;
+	_palette = 0;
+	_paletteColorCount = 0;
+}
+
+bool PCXDecoder::loadStream(Common::SeekableReadStream &stream) {
+	destroy();
+	
+	if (stream.readByte() != 0x0a)	// ZSoft PCX
+		return false;
+	
+	byte version = stream.readByte();	// 0 - 5
+	if (version > 5)
+		return false;
+	
+	bool compressed = stream.readByte(); // encoding, 1 = run length encoding
+	byte bitsPerPixel = stream.readByte();	// 1, 2, 4 or 8
+	
+	// Window
+	uint16 xMin = stream.readUint16LE();
+	uint16 yMin = stream.readUint16LE();
+	uint16 xMax = stream.readUint16LE();
+	uint16 yMax = stream.readUint16LE();
+	
+	uint16 width  = xMax - xMin + 1;
+	uint16 height = yMax - yMin + 1;
+	
+	if (xMax < xMin || yMax < yMin) {
+		warning("Invalid PCX image dimensions");
+		return false;
+	}
+		
+	stream.skip(4);	// HDpi, VDpi
+	
+	// Read the EGA palette (colormap)
+	_palette = new byte[16 * 3];
+	for (uint16 i = 0; i < 16; i++) {
+		_palette[i * 3 + 0] = stream.readByte();
+		_palette[i * 3 + 1] = stream.readByte();
+		_palette[i * 3 + 2] = stream.readByte();
+	}
+
+	if (stream.readByte() != 0)	// reserved, should be set to 0
+		return false;
+	
+	byte nPlanes = stream.readByte();
+	uint16 bytesPerLine = stream.readUint16LE();
+	uint16 bytesPerscanLine = nPlanes * bytesPerLine;
+	
+	if (bytesPerscanLine < width * bitsPerPixel * nPlanes / 8) {
+		warning("PCX data is corrupted");
+		return false;
+	}
+	
+	stream.skip(60);	// PaletteInfo, HscreenSize, VscreenSize, Filler
+	
+	_surface = new Graphics::Surface();
+	
+	byte *scanLine = new byte[bytesPerscanLine];
+	byte *dst;
+	int x, y;
+	
+	if (nPlanes == 3 && bitsPerPixel == 8) {	// 24bpp
+		Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+		_surface->create(width, height, format);
+		dst = (byte *)_surface->pixels;
+		_paletteColorCount = 0;
+
+		for (y = 0; y < height; y++) {
+			decodeRLE(stream, scanLine, bytesPerscanLine, compressed);
+
+			for (x = 0; x < width; x++) {
+				byte b = scanLine[x];
+				byte g = scanLine[x +  bytesPerLine];
+				byte r = scanLine[x + (bytesPerLine << 1)];
+				uint32 color = format.RGBToColor(r, g, b);
+
+				*((uint32 *)dst) = color;
+				dst += format.bytesPerPixel;
+			}
+		}
+	} else if (nPlanes == 1 && bitsPerPixel == 8) {	// 8bpp indexed
+		_surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+		dst = (byte *)_surface->pixels;
+		_paletteColorCount = 16;
+
+		for (y = 0; y < height; y++, dst += _surface->pitch) {
+			decodeRLE(stream, scanLine, bytesPerscanLine, compressed);
+			memcpy(dst, scanLine, width);
+		}
+		
+		if (version == 5) {
+			if (stream.readByte() != 12) {
+				warning("Expected a palette after the PCX image data");
+				delete[] scanLine;
+				return false;
+			}
+		
+			// Read the VGA palette
+			delete[] _palette;
+			_palette = new byte[256 * 3];
+			for (uint16 i = 0; i < 256; i++) {
+				_palette[i * 3 + 0] = stream.readByte();
+				_palette[i * 3 + 1] = stream.readByte();
+				_palette[i * 3 + 2] = stream.readByte();
+			}
+
+			_paletteColorCount = 256;
+		}
+	} else if ((nPlanes == 2 || nPlanes == 3 || nPlanes == 4) && bitsPerPixel == 1) {	// planar, 4, 8 or 16 colors
+		_surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+		dst = (byte *)_surface->pixels;
+		_paletteColorCount = 16;
+
+		for (y = 0; y < height; y++, dst += _surface->pitch) {
+			decodeRLE(stream, scanLine, bytesPerscanLine, compressed);
+
+			for (x = 0; x < width; x++) {
+				int m = 0x80 >> (x & 7), v = 0;
+				for (int i = nPlanes - 1; i >= 0; i--) {
+					v <<= 1;
+					v  += (scanLine[i * bytesPerLine + (x >> 3)] & m) == 0 ? 0 : 1;
+				}
+				dst[x] = v;
+			}
+		}
+	} else {
+		// Known unsupported case: 1 plane and bpp < 8 (1, 2 or 4)
+		warning("Invalid PCX file (%d planes, %d bpp)", nPlanes, bitsPerPixel);
+		delete[] scanLine;
+		return false;
+	}
+
+	delete[] scanLine;
+	
+	return true;
+}
+
+void PCXDecoder::decodeRLE(Common::SeekableReadStream &stream, byte *dst, uint32 bytesPerscanLine, bool compressed) {
+	uint32 i = 0;
+	byte run, value;
+
+	if (compressed) {
+		while (i < bytesPerscanLine) {
+			run = 1;
+			value = stream.readByte();
+			if (value >= 0xc0) {
+				run = value & 0x3f;
+				value = stream.readByte();
+			}
+			while (i < bytesPerscanLine && run--)
+				dst[i++] = value;
+		}
+	} else {
+		stream.read(dst, bytesPerscanLine);
+	}
+}
+
+} // End of namespace Graphics
diff --git a/graphics/decoders/pcx.h b/graphics/decoders/pcx.h
new file mode 100644
index 0000000..bcff754
--- /dev/null
+++ b/graphics/decoders/pcx.h
@@ -0,0 +1,68 @@
+/* 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.
+ */
+
+/**
+ * PCX decoder used in engines:
+ *  - dreamweb
+ *  - hugo
+ *  - queen
+ *  - tucker
+ */
+
+#ifndef GRAPHICS_DECODERS_PCX_H
+#define GRAPHICS_DECODERS_PCX_H
+
+#include "common/scummsys.h"
+#include "common/str.h"
+#include "graphics/decoders/image_decoder.h"
+
+namespace Common{
+class SeekableReadStream;
+}
+
+namespace Graphics {
+
+struct PixelFormat;
+struct Surface;
+
+class PCXDecoder : public ImageDecoder {
+public:
+	PCXDecoder();
+	virtual ~PCXDecoder();
+
+	// ImageDecoder API
+	void destroy();
+	virtual bool loadStream(Common::SeekableReadStream &stream);
+	virtual const Surface *getSurface() const { return _surface; }
+	const byte *getPalette() const { return _palette; }
+	uint16 getPaletteColorCount() const { return _paletteColorCount; }
+
+private:
+	void decodeRLE(Common::SeekableReadStream &stream, byte *dst, uint32 bytesPerScanline, bool compressed);
+	
+	Surface *_surface;
+	byte *_palette;
+	uint16 _paletteColorCount;
+};
+
+} // End of namespace Graphics
+
+#endif
diff --git a/graphics/module.mk b/graphics/module.mk
index e67efd2..f560d9d 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -25,6 +25,7 @@ MODULE_OBJS := \
 	yuv_to_rgb.o \
 	decoders/bmp.o \
 	decoders/jpeg.o \
+	decoders/pcx.o \
 	decoders/pict.o \
 	decoders/png.o \
 	decoders/tga.o


Commit: d182fe0221ed8c734c5aab3c18b006c0cc562af4
    https://github.com/scummvm/scummvm/commit/d182fe0221ed8c734c5aab3c18b006c0cc562af4
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2012-09-12T15:49:58-07:00

Commit Message:
QUEEN: Switch to the common PCX decoder

Changed paths:
    engines/queen/display.cpp



diff --git a/engines/queen/display.cpp b/engines/queen/display.cpp
index 83dc1a9..cd9a107 100644
--- a/engines/queen/display.cpp
+++ b/engines/queen/display.cpp
@@ -23,9 +23,13 @@
 
 #include "common/system.h"
 #include "common/events.h"
+#include "common/stream.h"
+#include "common/memstream.h"
 
 #include "graphics/cursorman.h"
 #include "graphics/palette.h"
+#include "graphics/surface.h"
+#include "graphics/decoders/pcx.h"
 
 #include "queen/display.h"
 #include "queen/input.h"
@@ -806,28 +810,22 @@ void Display::fill(uint8 *dstBuf, uint16 dstPitch, uint16 x, uint16 y, uint16 w,
 }
 
 void Display::decodePCX(const uint8 *src, uint32 srcSize, uint8 *dst, uint16 dstPitch, uint16 *w, uint16 *h, uint8 *pal, uint16 palStart, uint16 palEnd) {
-	*w = READ_LE_UINT16(src + 12);
-	*h = READ_LE_UINT16(src + 14);
+	Common::MemoryReadStream str(src, srcSize);
+
+	::Graphics::PCXDecoder pcx;
+	if (!pcx.loadStream(str))
+		error("Error while reading PCX image");
+
+	const ::Graphics::Surface *pcxSurface = pcx.getSurface();
+	if (pcxSurface->format.bytesPerPixel != 1)
+		error("Invalid bytes per pixel in PCX surface (%d)", pcxSurface->format.bytesPerPixel);
+	*w = pcxSurface->w;
+	*h = pcxSurface->h;
 
 	assert(palStart <= palEnd && palEnd <= 256);
-	const uint8 *palData = src + srcSize - 768;
-	memcpy(pal, palData + palStart * 3, (palEnd - palStart) * 3);
-
-	src += 128;
-	for (int y = 0; y < *h; ++y) {
-		uint8 *p = dst;
-		while (p < dst + *w) {
-			uint8 col = *src++;
-			if ((col & 0xC0) == 0xC0) {
-				uint8 len = col & 0x3F;
-				memset(p, *src++, len);
-				p += len;
-			} else {
-				*p++ = col;
-			}
-		}
-		dst += dstPitch;
-	}
+	memcpy(pal, pcx.getPalette() + palStart * 3, (palEnd - palStart) * 3);
+	for (uint16 y = 0; y < pcxSurface->h; y++)
+		memcpy(dst + y * dstPitch, pcxSurface->getBasePtr(0, y), pcxSurface->w);
 }
 
 void Display::decodeLBM(const uint8 *src, uint32 srcSize, uint8 *dst, uint16 dstPitch, uint16 *w, uint16 *h, uint8 *pal, uint16 palStart, uint16 palEnd, uint8 colorBase) {


Commit: 617545cb5f73c6ca8f14e3e5b1093e23fb68468b
    https://github.com/scummvm/scummvm/commit/617545cb5f73c6ca8f14e3e5b1093e23fb68468b
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2012-09-12T15:50:45-07:00

Commit Message:
TUCKER: Switch to the common PCX decoder

Changed paths:
    engines/tucker/resource.cpp



diff --git a/engines/tucker/resource.cpp b/engines/tucker/resource.cpp
index bee09f7..1b04f3f 100644
--- a/engines/tucker/resource.cpp
+++ b/engines/tucker/resource.cpp
@@ -29,6 +29,9 @@
 #include "audio/decoders/vorbis.h"
 #include "audio/decoders/wave.h"
 
+#include "graphics/surface.h"
+#include "graphics/decoders/pcx.h"
+
 #include "tucker/tucker.h"
 #include "tucker/graphics.h"
 
@@ -298,23 +301,21 @@ void TuckerEngine::loadImage(const char *fname, uint8 *dst, int type) {
 			return;
 		}
 	}
-	f.seek(128, SEEK_SET);
-	int size = 0;
-	while (size < 64000) {
-		int code = f.readByte();
-		if (code >= 0xC0) {
-			const int sz = code - 0xC0;
-			code = f.readByte();
-			memset(dst + size, code, sz);
-			size += sz;
-		} else {
-			dst[size++] = code;
-		}
-	}
+
+	::Graphics::PCXDecoder pcx;
+	if (!pcx.loadStream(f))
+		error("Error while reading PCX image");
+
+	const ::Graphics::Surface *pcxSurface = pcx.getSurface();
+	if (pcxSurface->format.bytesPerPixel != 1)
+		error("Invalid bytes per pixel in PCX surface (%d)", pcxSurface->format.bytesPerPixel);
+	if (pcxSurface->w != 320 || pcxSurface->h != 200)
+		error("Invalid PCX surface size (%d x %d)", pcxSurface->w, pcxSurface->h);
+	for (uint16 y = 0; y < pcxSurface->h; y++)
+		memcpy(dst + y * 320, pcxSurface->getBasePtr(0, y), pcxSurface->w);
+
 	if (type != 0) {
-		if (f.readByte() != 12)
-			return;
-		f.read(_currentPalette, 768);
+		memcpy(_currentPalette, pcx.getPalette(), 3 * 256);
 		setBlackPalette();
 	}
 }


Commit: 28733463faee6231ed2a48d55f0cbfe73d05aa14
    https://github.com/scummvm/scummvm/commit/28733463faee6231ed2a48d55f0cbfe73d05aa14
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2012-09-12T15:51:01-07:00

Commit Message:
DREAMWEB: Switch to the common PCX decoder

Changed paths:
    engines/dreamweb/vgagrafx.cpp



diff --git a/engines/dreamweb/vgagrafx.cpp b/engines/dreamweb/vgagrafx.cpp
index ec306c4..50c0ef3 100644
--- a/engines/dreamweb/vgagrafx.cpp
+++ b/engines/dreamweb/vgagrafx.cpp
@@ -23,6 +23,7 @@
 #include "dreamweb/dreamweb.h"
 #include "engines/util.h"
 #include "graphics/surface.h"
+#include "graphics/decoders/pcx.h"
 
 namespace DreamWeb {
 
@@ -152,70 +153,33 @@ void DreamWebEngine::setMode() {
 void DreamWebEngine::showPCX(const Common::String &suffix) {
 	Common::String name = getDatafilePrefix() + suffix;
 	Common::File pcxFile;
-
 	if (!pcxFile.open(name)) {
 		warning("showpcx: Could not open '%s'", name.c_str());
 		return;
 	}
 
-	uint8 *mainGamePal;
-	int i, j;
+	Graphics::PCXDecoder pcx;
+	if (!pcx.loadStream(pcxFile)) {
+		warning("showpcx: Could not process '%s'", name.c_str());
+		return;
+	}
 
 	// Read the 16-color palette into the 'maingamepal' buffer. Note that
 	// the color components have to be adjusted from 8 to 6 bits.
-
-	pcxFile.seek(16, SEEK_SET);
-	mainGamePal = _mainPal;
-	pcxFile.read(mainGamePal, 48);
-
-	memset(mainGamePal + 48, 0xff, 720);
-	for (i = 0; i < 48; i++) {
-		mainGamePal[i] >>= 2;
+	memset(_mainPal, 0xff, 256 * 3);
+	memcpy(_mainPal, pcx.getPalette(), 48);
+	for (int i = 0; i < 48; i++) {
+		_mainPal[i] >>= 2;
 	}
 
-	// Decode the image data.
-
 	Graphics::Surface *s = g_system->lockScreen();
-	Common::Rect rect(640, 480);
-
-	s->fillRect(rect, 0);
-	pcxFile.seek(128, SEEK_SET);
-
-	for (int y = 0; y < 480; y++) {
-		byte *dst = (byte *)s->getBasePtr(0, y);
-		int decoded = 0;
-
-		while (decoded < 320) {
-			byte col = pcxFile.readByte();
-			byte len;
-
-			if ((col & 0xc0) == 0xc0) {
-				len = col & 0x3f;
-				col = pcxFile.readByte();
-			} else {
-				len = 1;
-			}
-
-			// The image uses 16 colors and is stored as four bit
-			// planes, one for each bit of the color, least
-			// significant bit plane first.
-
-			for (i = 0; i < len; i++) {
-				int plane = decoded / 80;
-				int pos = decoded % 80;
-
-				for (j = 0; j < 8; j++) {
-					byte bit = (col >> (7 - j)) & 1;
-					dst[8 * pos + j] |= (bit << plane);
-				}
-
-				decoded++;
-			}
-		}
-	}
-
+	s->fillRect(Common::Rect(640, 480), 0);
+	const Graphics::Surface *pcxSurface = pcx.getSurface();
+	if (pcxSurface->format.bytesPerPixel != 1)
+		error("Invalid bytes per pixel in PCX surface (%d)", pcxSurface->format.bytesPerPixel);
+	for (uint16 y = 0; y < pcxSurface->h; y++)
+		memcpy((byte *)s->getBasePtr(0, y), pcxSurface->getBasePtr(0, y), pcxSurface->w);
 	g_system->unlockScreen();
-	pcxFile.close();
 }
 
 void DreamWebEngine::frameOutV(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, int16 x, int16 y) {


Commit: fb6a5a140d507b1160f5553fb45ca5e56a2bbe02
    https://github.com/scummvm/scummvm/commit/fb6a5a140d507b1160f5553fb45ca5e56a2bbe02
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2012-09-12T15:51:21-07:00

Commit Message:
HUGO: Switch to the common PCX decoder

Changed paths:
    engines/hugo/file.cpp
    engines/hugo/file.h



diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp
index 15ee06c..5945579 100644
--- a/engines/hugo/file.cpp
+++ b/engines/hugo/file.cpp
@@ -32,7 +32,11 @@
 #include "common/savefile.h"
 #include "common/textconsole.h"
 #include "common/config-manager.h"
+
+#include "graphics/surface.h"
+#include "graphics/decoders/pcx.h"
 #include "graphics/thumbnail.h"
+
 #include "gui/saveload.h"
 
 #include "hugo/hugo.h"
@@ -88,66 +92,33 @@ const char *FileManager::getUifFilename() const {
 }
 
 /**
- * Convert 4 planes (RGBI) data to 8-bit DIB format
- * Return original plane data ptr
- */
-byte *FileManager::convertPCC(byte *p, const uint16 y, const uint16 bpl, ImagePtr dataPtr) const {
-	debugC(2, kDebugFile, "convertPCC(byte *p, %d, %d, ImagePtr dataPtr)", y, bpl);
-
-	dataPtr += y * bpl * 8;                         // Point to correct DIB line
-	for (int16 r = 0, g = bpl, b = g + bpl, i = b + bpl; r < bpl; r++, g++, b++, i++) { // Each byte in all planes
-		for (int8 bit = 7; bit >= 0; bit--) {       // Each bit in byte
-			*dataPtr++ = (((p[r] >> bit & 1) << 0) |
-			              ((p[g] >> bit & 1) << 1) |
-			              ((p[b] >> bit & 1) << 2) |
-			              ((p[i] >> bit & 1) << 3));
-		}
-	}
-	return p;
-}
-
-/**
  * Read a pcx file of length len.  Use supplied seqPtr and image_p or
  * allocate space if NULL.  Name used for errors.  Returns address of seqPtr
  * Set first TRUE to initialize b_index (i.e. not reading a sequential image in file).
  */
-Seq *FileManager::readPCX(Common::ReadStream &f, Seq *seqPtr, byte *imagePtr, const bool firstFl, const char *name) {
+Seq *FileManager::readPCX(Common::SeekableReadStream &f, Seq *seqPtr, byte *imagePtr, const bool firstFl, const char *name) {
 	debugC(1, kDebugFile, "readPCX(..., %s)", name);
 
-	// Read in the PCC header and check consistency
-	_PCCHeader._mfctr = f.readByte();
-	_PCCHeader._vers = f.readByte();
-	_PCCHeader._enc = f.readByte();
-	_PCCHeader._bpx = f.readByte();
-	_PCCHeader._x1 = f.readUint16LE();
-	_PCCHeader._y1 = f.readUint16LE();
-	_PCCHeader._x2 = f.readUint16LE();
-	_PCCHeader._y2 = f.readUint16LE();
-	_PCCHeader._xres = f.readUint16LE();
-	_PCCHeader._yres = f.readUint16LE();
-	f.read(_PCCHeader._palette, sizeof(_PCCHeader._palette));
-	_PCCHeader._vmode = f.readByte();
-	_PCCHeader._planes = f.readByte();
-	_PCCHeader._bytesPerLine = f.readUint16LE();
-	f.read(_PCCHeader._fill2, sizeof(_PCCHeader._fill2));
-
-	if (_PCCHeader._mfctr != 10)
-		error("Bad data file format: %s", name);
-
 	// Allocate memory for Seq if 0
 	if (seqPtr == 0) {
 		if ((seqPtr = (Seq *)malloc(sizeof(Seq))) == 0)
 			error("Insufficient memory to run game.");
 	}
 
+	Graphics::PCXDecoder pcx;
+	if (!pcx.loadStream(f))
+		error("Error while reading PCX image");
+
+	const Graphics::Surface *pcxSurface = pcx.getSurface();
+	if (pcxSurface->format.bytesPerPixel != 1)
+		error("Invalid bytes per pixel in PCX surface (%d)", pcxSurface->format.bytesPerPixel);
+
 	// Find size of image data in 8-bit DIB format
 	// Note save of x2 - marks end of valid data before garbage
-	uint16 bytesPerLine4 = _PCCHeader._bytesPerLine * 4; // 4-bit bpl
-	seqPtr->_bytesPerLine8 = bytesPerLine4 * 2;      // 8-bit bpl
-	seqPtr->_lines = _PCCHeader._y2 - _PCCHeader._y1 + 1;
-	seqPtr->_x2 = _PCCHeader._x2 - _PCCHeader._x1 + 1;
+	seqPtr->_lines = pcxSurface->h;
+	seqPtr->_x2 = seqPtr->_bytesPerLine8 = pcxSurface->w;
 	// Size of the image
-	uint16 size = seqPtr->_lines * seqPtr->_bytesPerLine8;
+	uint16 size = pcxSurface->w * pcxSurface->h;
 
 	// Allocate memory for image data if NULL
 	if (imagePtr == 0)
@@ -156,26 +127,9 @@ Seq *FileManager::readPCX(Common::ReadStream &f, Seq *seqPtr, byte *imagePtr, co
 	assert(imagePtr);
 
 	seqPtr->_imagePtr = imagePtr;
+	for (uint16 y = 0; y < pcxSurface->h; y++)
+		memcpy(imagePtr + y * pcxSurface->pitch, pcxSurface->getBasePtr(0, y), pcxSurface->w);
 
-	// Process the image data, converting to 8-bit DIB format
-	uint16 y = 0;                                   // Current line index
-	byte  pline[kXPix];                             // Hold 4 planes of data
-	byte  *p = pline;                               // Ptr to above
-	while (y < seqPtr->_lines) {
-		byte c = f.readByte();
-		if ((c & kRepeatMask) == kRepeatMask) {
-			byte d = f.readByte();                  // Read data byte
-			for (int i = 0; i < (c & kLengthMask); i++) {
-				*p++ = d;
-				if ((uint16)(p - pline) == bytesPerLine4)
-					p = convertPCC(pline, y++, _PCCHeader._bytesPerLine, imagePtr);
-			}
-		} else {
-			*p++ = c;
-			if ((uint16)(p - pline) == bytesPerLine4)
-				p = convertPCC(pline, y++, _PCCHeader._bytesPerLine, imagePtr);
-		}
-	}
 	return seqPtr;
 }
 
diff --git a/engines/hugo/file.h b/engines/hugo/file.h
index 1438bd2..44f257a 100644
--- a/engines/hugo/file.h
+++ b/engines/hugo/file.h
@@ -112,16 +112,13 @@ protected:
 	Common::File _sceneryArchive1;                  // Handle for scenery file
 	Common::File _objectsArchive;                   // Handle for objects file
 
-	PCCHeader _PCCHeader;
-
-	Seq *readPCX(Common::ReadStream &f, Seq *seqPtr, byte *imagePtr, const bool firstFl, const char *name);
+	Seq *readPCX(Common::SeekableReadStream &f, Seq *seqPtr, byte *imagePtr, const bool firstFl, const char *name);
 
 	// If this is the first call, read the lookup table
 	bool _hasReadHeader;
 	SoundHdr _soundHdr[kMaxSounds];                    // Sound lookup table
 
 private:
-	byte *convertPCC(byte *p, const uint16 y, const uint16 bpl, ImagePtr dataPtr) const;
 	UifHdr *getUIFHeader(const Uif id);
 };
 


Commit: ef671f20b108de79c006cdc95fc6ee613e46ab98
    https://github.com/scummvm/scummvm/commit/ef671f20b108de79c006cdc95fc6ee613e46ab98
Author: Filippos Karapetis (md5 at scummvm.org)
Date: 2012-09-13T17:35:18-07:00

Commit Message:
HUGO: Use surface width instead of its pitch when copying to raw memory blobs

This is according to wjp's suggestion - the pitch didn't make sense there

Changed paths:
    engines/hugo/file.cpp



diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp
index 5945579..1758f3f 100644
--- a/engines/hugo/file.cpp
+++ b/engines/hugo/file.cpp
@@ -128,7 +128,7 @@ Seq *FileManager::readPCX(Common::SeekableReadStream &f, Seq *seqPtr, byte *imag
 
 	seqPtr->_imagePtr = imagePtr;
 	for (uint16 y = 0; y < pcxSurface->h; y++)
-		memcpy(imagePtr + y * pcxSurface->pitch, pcxSurface->getBasePtr(0, y), pcxSurface->w);
+		memcpy(imagePtr + y * pcxSurface->w, pcxSurface->getBasePtr(0, y), pcxSurface->w);
 
 	return seqPtr;
 }


Commit: c0babb010a7f803e54f3021e9560d77baf69fdb8
    https://github.com/scummvm/scummvm/commit/c0babb010a7f803e54f3021e9560d77baf69fdb8
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2012-09-16T14:06:42-07:00

Commit Message:
Merge pull request #278 from bluegr/pcxdecoder

GRAPHICS: Add a PCX decoder

Changed paths:
  A graphics/decoders/pcx.cpp
  A graphics/decoders/pcx.h
    engines/dreamweb/vgagrafx.cpp
    engines/hugo/file.cpp
    engines/hugo/file.h
    engines/queen/display.cpp
    engines/tucker/resource.cpp
    graphics/module.mk









More information about the Scummvm-git-logs mailing list