[Scummvm-git-logs] scummvm master -> 0aedc770e43b25e8c1487552e66d1f2687ddc4d3

sev- noreply at scummvm.org
Tue Dec 26 16:52:57 UTC 2023


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

Summary:
ff6c4424bd IMAGE: Added PackBitsRgn and BitsRgn opcodes to PICT decoder
0aedc770e4 SCUMM: Remove custom PICTv1 decoder in favor of general one


Commit: ff6c4424bd3ce34f367081921f5c7e5b10871b42
    https://github.com/scummvm/scummvm/commit/ff6c4424bd3ce34f367081921f5c7e5b10871b42
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-12-26T17:52:52+01:00

Commit Message:
IMAGE: Added PackBitsRgn and BitsRgn opcodes to PICT decoder

Used in SCUMM Mac GUI

Changed paths:
    image/pict.cpp
    image/pict.h


diff --git a/image/pict.cpp b/image/pict.cpp
index 392a6f298b3..d4c79b1dadb 100644
--- a/image/pict.cpp
+++ b/image/pict.cpp
@@ -68,6 +68,9 @@ void PICTDecoder::setupOpcodesCommon() {
 	OPCODE(0x0011, o_versionOp, "VersionOp");
 	OPCODE(0x001E, o_nop, "DefHilite");
 	OPCODE(0x0028, o_longText, "LongText");
+	OPCODE(0x0091, o_bitsRgn, "BitsRgn");
+	OPCODE(0x0099, o_packBitsRgn, "PackBitsRgn");
+	OPCODE(0x00A0, o_shortComment, "ShortComment");
 	OPCODE(0x00A1, o_longComment, "LongComment");
 	OPCODE(0x00FF, o_opEndPic, "OpEndPic");
 	OPCODE(0x0C00, o_headerOp, "HeaderOp");
@@ -161,6 +164,20 @@ void PICTDecoder::o_longText(Common::SeekableReadStream &stream) {
 	stream.skip(stream.readByte());
 }
 
+void PICTDecoder::o_bitsRgn(Common::SeekableReadStream &stream) {
+	// Copy unpacked data with clipped region (8bpp or lower)
+	unpackBitsRgn(stream, false);
+}
+
+void PICTDecoder::o_packBitsRgn(Common::SeekableReadStream &stream) {
+	unpackBitsRgn(stream, true);
+}
+
+void PICTDecoder::o_shortComment(Common::SeekableReadStream &stream) {
+	// Ignore
+	stream.readUint16BE();
+}
+
 void PICTDecoder::o_longComment(Common::SeekableReadStream &stream) {
 	// Ignore
 	stream.readUint16BE();
@@ -452,6 +469,89 @@ void PICTDecoder::unpackBitsRect(Common::SeekableReadStream &stream, bool withPa
 	delete[] buffer;
 }
 
+void PICTDecoder::unpackBitsRgn(Common::SeekableReadStream &stream, bool compressed) {
+	int x1, x2, y1, y2;
+	int size = 0;
+	stream.skip(2);	// Skip rowBytes
+
+	if (!_outputSurface) {
+		_outputSurface = new Graphics::Surface();
+		_outputSurface->create(_imageRect.width(), _imageRect.height(), Graphics::PixelFormat::createFormatCLUT8());
+	}
+
+	y1 = stream.readSint16BE();
+	x1 = stream.readSint16BE();
+	y2 = stream.readSint16BE();
+	x2 = stream.readSint16BE();
+
+	stream.skip(8);	// Skip srcRect
+	stream.skip(8);	// Skip dstRect
+	stream.skip(2);	// Skip mode
+	stream.skip(stream.readUint16BE() - 2);
+
+	int x = 0;
+	int y = 0;
+	byte value;
+
+	if (!compressed) {
+		for (y = y1; y < y2 && y < _imageRect.height(); y++) {
+			byte b = stream.readByte();
+			byte bit = 0x80;
+
+			for (x = x1; x < x2 && x < _imageRect.width(); x++) {
+				if (b & bit)
+					_outputSurface->setPixel(x, y, 0x0F);
+				else
+					_outputSurface->setPixel(x, y, 0x00);
+
+				bit >>= 1;
+
+				if (bit == 0) {
+					b = stream.readByte();
+					bit = 0x80;
+				}
+			}
+		}
+	} else {
+		for (y = y1; y < y2 && y < _imageRect.height(); y++) {
+			x = x1;
+			size = stream.readByte();
+
+			while (size > 0) {
+				byte count = stream.readByte();
+				size--;
+
+				bool repeat;
+
+				if (count >= 128) {
+					// Repeat value
+					count = 256 - count;
+					repeat = true;
+					value = stream.readByte();
+					size--;
+				} else {
+					// Copy values
+					repeat = false;
+					value = 0;
+				}
+
+				for (int j = 0; j <= count; j++) {
+					if (!repeat) {
+						value = stream.readByte();
+						size--;
+					}
+					for (int k = 7; k >= 0 && x < x2 && x < _imageRect.width(); k--, x++) {
+						if (value & (1 << k))
+							_outputSurface->setPixel(x, y, 0x0F);
+						else
+							_outputSurface->setPixel(x, y, 0x00);
+					}
+				}
+			}
+		}
+	}
+}
+
 void PICTDecoder::unpackBitsLine(byte *out, uint32 length, Common::SeekableReadStream *data, byte bitsPerPixel, byte bytesPerPixel) {
 	uint32 dataDecoded = 0;
 	byte bytesPerDecode = (bytesPerPixel == 2) ? 2 : 1;
diff --git a/image/pict.h b/image/pict.h
index bb0c1c4405e..0a38a96bc94 100644
--- a/image/pict.h
+++ b/image/pict.h
@@ -95,6 +95,7 @@ private:
 	int _version;
 
 	// Utility Functions
+	void unpackBitsRgn(Common::SeekableReadStream &stream, bool compressed);
 	void unpackBitsRect(Common::SeekableReadStream &stream, bool withPalette);
 	void unpackBitsLine(byte *out, uint32 length, Common::SeekableReadStream *stream, byte bitsPerPixel, byte bytesPerPixel);
 	void skipBitsRect(Common::SeekableReadStream &stream, bool withPalette);
@@ -123,6 +124,9 @@ private:
 	DECLARE_OPCODE(o_txRatio);
 	DECLARE_OPCODE(o_versionOp);
 	DECLARE_OPCODE(o_longText);
+	DECLARE_OPCODE(o_bitsRgn);
+	DECLARE_OPCODE(o_packBitsRgn);
+	DECLARE_OPCODE(o_shortComment);
 	DECLARE_OPCODE(o_longComment);
 	DECLARE_OPCODE(o_opEndPic);
 	DECLARE_OPCODE(o_headerOp);


Commit: 0aedc770e43b25e8c1487552e66d1f2687ddc4d3
    https://github.com/scummvm/scummvm/commit/0aedc770e43b25e8c1487552e66d1f2687ddc4d3
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-12-26T17:52:52+01:00

Commit Message:
SCUMM: Remove custom PICTv1 decoder in favor of general one

Changed paths:
    engines/scumm/macgui/macgui_impl.cpp
    engines/scumm/macgui/macgui_impl.h


diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 0ecc514fcd9..9281283237f 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -469,194 +469,66 @@ Graphics::Surface *MacGuiImpl::loadPict(int id) {
 	Common::SeekableReadStream *res = resource.getResource(MKTAG('P', 'I', 'C', 'T'), id);
 
 	// IQ logos are PICT v2
-	if (id == 4000 || id == 4001) {
-		Image::PICTDecoder pict;
-		if (pict.loadStream(*res)) {
-			const Graphics::Surface *s1 = pict.getSurface();
-			const byte *palette = pict.getPalette();
-
-			s = new Graphics::Surface();
-			s->create(s1->w, s1->h, Graphics::PixelFormat::createFormatCLUT8());
-
-			// The palette doesn't match the game's palette at all, so remap
-			// the colors to the custom area of the palette. It's assumed that
-			// only one such picture will be loaded at a time.
-			//
-			// But we still match black and white to 0 and 15 to make sure they
-			// mach exactly.
-
-			int black = -1;
-			int white = -1;
-
-			for (int i = 0; i < pict.getPaletteColorCount(); i++) {
-				int r = palette[3 * i];
-				int g = palette[3 * i + 1];
-				int b = palette[3 * i + 2];
-
-				if (r == 0 && g == 0 && b == 0)
-					black = i;
-				else if (r == 255 && g == 255 && b == 255)
-					white = i;
-			}
-
-			if (palette) {
-				_system->getPaletteManager()->setPalette(palette, kCustomColor, pict.getPaletteColorCount());
-
-				for (int y = 0; y < s->h; y++) {
-					for (int x = 0; x < s->w; x++) {
-						int color = s1->getPixel(x, y);
+	Image::PICTDecoder pict;
+	if (pict.loadStream(*res)) {
+		warning("DECODED");
+		const Graphics::Surface *s1 = pict.getSurface();
+		const byte *palette = pict.getPalette();
+
+		s = new Graphics::Surface();
+		s->create(s1->w, s1->h, Graphics::PixelFormat::createFormatCLUT8());
+
+		// The palette doesn't match the game's palette at all, so remap
+		// the colors to the custom area of the palette. It's assumed that
+		// only one such picture will be loaded at a time.
+		//
+		// But we still match black and white to 0 and 15 to make sure they
+		// mach exactly.
 
-						if (color == black)
-							color = kBlack;
-						else if (color == white)
-							color = kWhite;
-						else
-							color = kCustomColor + color;
+		int black = -1;
+		int white = -1;
 
-						s->setPixel(x, y, color);
-					}
-				}
-			} else
-				s->copyFrom(*s1);
+		for (int i = 0; i < pict.getPaletteColorCount(); i++) {
+			int r = palette[3 * i];
+			int g = palette[3 * i + 1];
+			int b = palette[3 * i + 2];
 
+			if (r == 0 && g == 0 && b == 0)
+				black = i;
+			else if (r == 255 && g == 255 && b == 255)
+				white = i;
 		}
-	} else {
-		s = decodePictV1(res);
-	}
-
-	delete res;
-	resource.close();
-
-	return s;
-}
-
-Graphics::Surface *MacGuiImpl::decodePictV1(Common::SeekableReadStream *res) {
-	uint16 size = res->readUint16BE();
-
-	uint16 top = res->readUint16BE();
-	uint16 left = res->readUint16BE();
-	uint16 bottom = res->readUint16BE();
-	uint16 right = res->readUint16BE();
-
-	int width = right - left;
-	int height = bottom - top;
-
-	Graphics::Surface *s = new Graphics::Surface();
-	s->create(right - left, bottom - top, Graphics::PixelFormat::createFormatCLUT8());
 
-	bool endOfPicture = false;
+		if (!pict.getPaletteColorCount()) {
+			black = 0xff;
+			white = 0x00;
+		}
 
-	while (!endOfPicture) {
-		byte opcode = res->readByte();
-		byte value;
-		int x1, x2, y1, y2;
+		if (palette) {
+			_system->getPaletteManager()->setPalette(palette, kCustomColor, pict.getPaletteColorCount());
 
-		int x = 0;
-		int y = 0;
-		bool compressed = false;
+			for (int y = 0; y < s->h; y++) {
+				for (int x = 0; x < s->w; x++) {
+					int color = s1->getPixel(x, y);
 
-		switch (opcode) {
-		case 0x01: // clipRgn
-			// The clip region is not important
-			res->skip(res->readUint16BE() - 2);
-			break;
+					if (color == black)
+						color = kBlack;
+					else if (color == white)
+						color = kWhite;
+					else
+						color = kCustomColor + color;
 
-		case 0x11: // picVersion
-			value = res->readByte();
-			assert(value == 1);
-			break;
-
-		case 0x99: // PackBitsRgn
-			compressed = true;
-			// Fall through
-
-		case 0x91: // BitsRgn
-			res->skip(2);	// Skip rowBytes
-
-			y1 = res->readSint16BE();
-			x1 = res->readSint16BE();
-			y2 = res->readSint16BE();
-			x2 = res->readSint16BE();
-
-			res->skip(8);	// Skip srcRect
-			res->skip(8);	// Skip dstRect
-			res->skip(2);	// Skip mode
-			res->skip(res->readUint16BE() - 2);	// Skip maskRgn
-
-			if (!compressed) {
-				for (y = y1; y < y2 && y < height; y++) {
-					byte b = res->readByte();
-					byte bit = 0x80;
-
-					for (x = x1; x < x2 && x < width; x++) {
-						if (b & bit)
-							s->setPixel(x, y, kBlack);
-						else
-							s->setPixel(x, y, kWhite);
-
-						bit >>= 1;
-
-						if (bit == 0) {
-							b = res->readByte();
-							bit = 0x80;
-						}
-					}
-				}
-			} else {
-				for (y = y1; y < y2 && y < height; y++) {
-					x = x1;
-					size = res->readByte();
-
-					while (size > 0) {
-						byte count = res->readByte();
-						size--;
-
-						bool repeat;
-
-						if (count >= 128) {
-							// Repeat value
-							count = 256 - count;
-							repeat = true;
-							value = res->readByte();
-							size--;
-						} else {
-							// Copy values
-							repeat = false;
-							value = 0;
-						}
-
-						for (int j = 0; j <= count; j++) {
-							if (!repeat) {
-								value = res->readByte();
-								size--;
-							}
-							for (int k = 7; k >= 0 && x < x2 && x < width; k--, x++) {
-								if (value & (1 << k))
-									s->setPixel(x, y, kBlack);
-								else
-									s->setPixel(x, y, kWhite);
-							}
-						}
-					}
+					s->setPixel(x, y, color);
 				}
 			}
+		} else
+			s->copyFrom(*s1);
 
-			break;
-
-		case 0xA0: // shortComment
-			res->skip(2);
-			break;
-
-		case 0xFF: // EndOfPicture
-			endOfPicture = true;
-			break;
-
-		default:
-			warning("decodePictV1: Unknown opcode: 0x%02x", opcode);
-			break;
-		}
 	}
 
+	delete res;
+	resource.close();
+
 	return s;
 }
 
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 8b2a1f739a1..6c9a4c8201b 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -612,7 +612,6 @@ public:
 	virtual const Graphics::Font *getFontByScummId(int32 id) = 0;
 
 	Graphics::Surface *loadPict(int id);
-	Graphics::Surface *decodePictV1(Common::SeekableReadStream *res);
 
 	virtual bool isVerbGuiActive() const { return false; }
 	virtual void reset() {}




More information about the Scummvm-git-logs mailing list