[Scummvm-git-logs] scummvm master -> bb427be636e61f81ecc1b9acbc23d984d86937d3

sev- noreply at scummvm.org
Sun Jul 3 23:36:28 UTC 2022


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

Summary:
1edcbcb53e JANITORIAL: Fix formatting
c87c02c5ae GRAPHICS: Return flag if palette was updated for the palette lookup
c01657fc6e DIRECTOR: Implement naive image dithering
d37a01fd2c GRAPHICS: MACGUI: Fix rendering for 32bpp mode
bb427be636 DIRECTOR: Implement Floyd-Steinberg dithering


Commit: 1edcbcb53e3ce7e7bc1221e5b6af43d32da9cb54
    https://github.com/scummvm/scummvm/commit/1edcbcb53e3ce7e7bc1221e5b6af43d32da9cb54
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2022-07-04T01:36:14+02:00

Commit Message:
JANITORIAL: Fix formatting

Changed paths:
    engines/director/castmember.cpp


diff --git a/engines/director/castmember.cpp b/engines/director/castmember.cpp
index 82192288a5b..d5f86a47793 100644
--- a/engines/director/castmember.cpp
+++ b/engines/director/castmember.cpp
@@ -195,7 +195,7 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Common::SeekableRe
 	_tag = castTag;
 }
 
-BitmapCastMember::BitmapCastMember(Cast* cast, uint16 castId, Image::ImageDecoder* img, uint8 flags1)
+BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Image::ImageDecoder *img, uint8 flags1)
 	: CastMember(cast, castId) {
 	_type = kCastBitmap;
 	_matte = nullptr;


Commit: c87c02c5ae575f9283423bf83bcc8bed461e2120
    https://github.com/scummvm/scummvm/commit/c87c02c5ae575f9283423bf83bcc8bed461e2120
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2022-07-04T01:36:18+02:00

Commit Message:
GRAPHICS: Return flag if palette was updated for the palette lookup

Changed paths:
    graphics/palette.cpp
    graphics/palette.h


diff --git a/graphics/palette.cpp b/graphics/palette.cpp
index 56c6a45a2f9..aae0fdf8bb2 100644
--- a/graphics/palette.cpp
+++ b/graphics/palette.cpp
@@ -32,14 +32,16 @@ PaletteLookup::PaletteLookup(const byte *palette, uint len)  {
 	memcpy(_palette, palette, len * 3);
 }
 
-void PaletteLookup::setPalette(const byte *palette, uint len)  {
+bool PaletteLookup::setPalette(const byte *palette, uint len)  {
 	// Check if the passed palette matched the one we have
 	if (len == _paletteSize && !memcmp(_palette, palette, len * 3))
-		return;
+		return false;
 
 	_paletteSize = len;
 	memcpy(_palette, palette, len * 3);
 	_colorHash.clear();
+
+	return true;
 }
 
 byte PaletteLookup::findBestColor(byte cr, byte cg, byte cb) {
diff --git a/graphics/palette.h b/graphics/palette.h
index 3603d62ecdf..011b86e652f 100644
--- a/graphics/palette.h
+++ b/graphics/palette.h
@@ -128,8 +128,10 @@ public:
 	 *
 	 * @param palette   the palette data, in interleaved RGB format
 	 * @param len       the number of palette entries to be read
+	 *
+	 * @return true if palette was changed and false if it was the same
 	 */
-	void setPalette(const byte *palette, uint len);
+	bool setPalette(const byte *palette, uint len);
 
 	/**
 	 * @brief This method returns closest color from the palette


Commit: c01657fc6ef3e78e984d676768035cd565faa2a7
    https://github.com/scummvm/scummvm/commit/c01657fc6ef3e78e984d676768035cd565faa2a7
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2022-07-04T01:36:18+02:00

Commit Message:
DIRECTOR: Implement naive image dithering

Changed paths:
    engines/director/castmember.cpp
    engines/director/castmember.h


diff --git a/engines/director/castmember.cpp b/engines/director/castmember.cpp
index d5f86a47793..bb828dc5f62 100644
--- a/engines/director/castmember.cpp
+++ b/engines/director/castmember.cpp
@@ -93,6 +93,7 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Common::SeekableRe
 		: CastMember(cast, castId, stream) {
 	_type = kCastBitmap;
 	_img = nullptr;
+	_ditheredImg = nullptr;
 	_matte = nullptr;
 	_noMatte = false;
 	_bytes = 0;
@@ -202,6 +203,7 @@ BitmapCastMember::BitmapCastMember(Cast *cast, uint16 castId, Image::ImageDecode
 	_noMatte = false;
 	_bytes = 0;
 	_img = img;
+	_ditheredImg = nullptr;
 	_clut = -1;
 	_initialRect = Common::Rect(0, 0, img->getSurface()->w, img->getSurface()->h);
 	_pitch = img->getSurface()->pitch;
@@ -216,6 +218,9 @@ BitmapCastMember::~BitmapCastMember() {
 	if (_img)
 		delete _img;
 
+	if (_ditheredImg)
+		delete _ditheredImg;
+
 	if (_matte)
 		delete _matte;
 }
@@ -230,6 +235,11 @@ Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel
 	if (!bbox.width() || !bbox.height())
 		return nullptr;
 
+	// Check if we need to dither the image
+	if (g_director->_wm->_pixelformat.bytesPerPixel == 1 && _img->getSurface()->format.bytesPerPixel > 1) {
+		ditherImage();
+	}
+
 	Graphics::MacWidget *widget = new Graphics::MacWidget(g_director->getCurrentWindow(), bbox.left, bbox.top, bbox.width(), bbox.height(), g_director->_wm, false);
 
 	// scale for drawing a different size sprite
@@ -239,6 +249,13 @@ Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel
 }
 
 void BitmapCastMember::copyStretchImg(Graphics::Surface *surface, const Common::Rect &bbox) {
+	const Graphics::Surface *srcSurf;
+
+	if (_ditheredImg)
+		srcSurf = _ditheredImg;
+	else
+		srcSurf = _img->getSurface();
+
 	if (bbox.width() != _initialRect.width() || bbox.height() != _initialRect.height()) {
 
 		int scaleX = SCALE_THRESHOLD * _initialRect.width() / bbox.width();
@@ -247,18 +264,57 @@ void BitmapCastMember::copyStretchImg(Graphics::Surface *surface, const Common::
 		for (int y = 0, scaleYCtr = 0; y < bbox.height(); y++, scaleYCtr += scaleY) {
 			if (g_director->_wm->_pixelformat.bytesPerPixel == 1) {
 				for (int x = 0, scaleXCtr = 0; x < bbox.width(); x++, scaleXCtr += scaleX) {
-					const byte *src = (const byte *)_img->getSurface()->getBasePtr(scaleXCtr / SCALE_THRESHOLD, scaleYCtr / SCALE_THRESHOLD);
+					const byte *src = (const byte *)srcSurf->getBasePtr(scaleXCtr / SCALE_THRESHOLD, scaleYCtr / SCALE_THRESHOLD);
 					*(byte *)surface->getBasePtr(x, y) = *src;
 				}
 			} else {
 				for (int x = 0, scaleXCtr = 0; x < bbox.width(); x++, scaleXCtr += scaleX) {
-					const int *src = (const int *)_img->getSurface()->getBasePtr(scaleXCtr / SCALE_THRESHOLD, scaleYCtr / SCALE_THRESHOLD);
+					const int *src = (const int *)srcSurf->getBasePtr(scaleXCtr / SCALE_THRESHOLD, scaleYCtr / SCALE_THRESHOLD);
 					*(int *)surface->getBasePtr(x, y) = *src;
 				}
 			}
 		}
 	} else {
-		surface->copyFrom(*_img->getSurface());
+		surface->copyFrom(*srcSurf);
+	}
+}
+
+void BitmapCastMember::ditherImage() {
+	// If palette did not change, do not re-dither
+	if (!_paletteLookup.setPalette(g_director->_wm->getPalette(), g_director->_wm->getPaletteSize()))
+		return;
+
+	int bpp = _img->getSurface()->format.bytesPerPixel;
+
+	_ditheredImg = new Graphics::Surface;
+	_ditheredImg->create(_initialRect.width(), _initialRect.height(), g_director->_pixelformat);
+
+	for (int y = 0; y < _initialRect.height(); y++) {
+		const byte *src = (const byte *)_img->getSurface()->getBasePtr(0, y);
+		byte *dst = (byte *)_ditheredImg->getBasePtr(0, y);
+
+		for (int x = 0; x < _initialRect.width(); x++) {
+			uint32 color;
+
+			switch (bpp) {
+			case 2:
+				color = *((const uint16 *)src);
+				src += 2;
+				break;
+			case 4:
+				color = *((const uint32 *)src);
+				src += 4;
+				break;
+			default:
+				error("BitmapCastMember::ditherImage(): Unsupported bit depth: %d", bpp);
+			}
+
+			byte r, g, b;
+			_img->getSurface()->format.colorToRGB(color, r, g, b);
+
+			*dst = _paletteLookup.findBestColor(r, g, b);
+			dst++;
+		}
 	}
 }
 
diff --git a/engines/director/castmember.h b/engines/director/castmember.h
index c6a1a13a37c..5a3c43aa870 100644
--- a/engines/director/castmember.h
+++ b/engines/director/castmember.h
@@ -132,6 +132,7 @@ public:
 	bool setField(int field, const Datum &value) override;
 
 	Image::ImageDecoder *_img;
+	Graphics::Surface *_ditheredImg;
 	Graphics::FloodFill *_matte;
 
 	uint16 _pitch;
@@ -145,6 +146,11 @@ public:
 
 	uint32 _tag;
 	bool _noMatte;
+
+private:
+	void ditherImage();
+
+	Graphics::PaletteLookup _paletteLookup;
 };
 
 class DigitalVideoCastMember : public CastMember {


Commit: d37a01fd2cbd0ef4e59bbca117a80812543fb856
    https://github.com/scummvm/scummvm/commit/d37a01fd2cbd0ef4e59bbca117a80812543fb856
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2022-07-04T01:36:18+02:00

Commit Message:
GRAPHICS: MACGUI: Fix rendering for 32bpp mode

Changed paths:
    graphics/macgui/macwindowmanager.cpp


diff --git a/graphics/macgui/macwindowmanager.cpp b/graphics/macgui/macwindowmanager.cpp
index 0dce8cfffc4..21bd9368f92 100644
--- a/graphics/macgui/macwindowmanager.cpp
+++ b/graphics/macgui/macwindowmanager.cpp
@@ -795,7 +795,7 @@ void MacWindowManager::drawDesktop() {
 					byte r, g, b;
 					_desktopBmp->format.colorToRGB(color, r, g, b);
 					if (color > 0) {
-						*((byte *)_desktop->getBasePtr(i, j)) = _paletteLookup.findBestColor(r, g, b);
+						*((byte *)_desktop->getBasePtr(i, j)) = findBestColor(r, g, b);
 					}
 				} else {
 					*((uint32 *)_desktop->getBasePtr(i, j)) = color;
@@ -1270,7 +1270,7 @@ void MacWindowManager::popCursor() {
 ///////////////////
 // Palette stuff
 ///////////////////
-#define LOOKUPCOLOR(x) _color ## x = _paletteLookup.findBestColor(palette[kColor ## x * 3], palette[kColor ## x  * 3 + 1], palette[kColor ## x * 3 + 2]);
+#define LOOKUPCOLOR(x) _color ## x = findBestColor(palette[kColor ## x * 3], palette[kColor ## x  * 3 + 1], palette[kColor ## x * 3 + 2]);
 
 void MacWindowManager::passPalette(const byte *pal, uint size) {
 	if (_palette)
@@ -1329,7 +1329,7 @@ uint MacWindowManager::inverter(uint src) {
 		r = ~r;
 		g = ~g;
 		b = ~b;
-		_invertColorHash[src] = _paletteLookup.findBestColor(r, g, b);
+		_invertColorHash[src] = findBestColor(r, g, b);
 	} else {
 		uint32 alpha = _pixelformat.ARGBToColor(255, 0, 0, 0);
 		_invertColorHash[src] = ~(src & ~alpha) | alpha;


Commit: bb427be636e61f81ecc1b9acbc23d984d86937d3
    https://github.com/scummvm/scummvm/commit/bb427be636e61f81ecc1b9acbc23d984d86937d3
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2022-07-04T01:36:18+02:00

Commit Message:
DIRECTOR: Implement Floyd-Steinberg dithering

Changed paths:
    engines/director/castmember.cpp
    engines/director/castmember.h


diff --git a/engines/director/castmember.cpp b/engines/director/castmember.cpp
index bb828dc5f62..06f1a702ef4 100644
--- a/engines/director/castmember.cpp
+++ b/engines/director/castmember.cpp
@@ -237,7 +237,7 @@ Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel
 
 	// Check if we need to dither the image
 	if (g_director->_wm->_pixelformat.bytesPerPixel == 1 && _img->getSurface()->format.bytesPerPixel > 1) {
-		ditherImage();
+		ditherFloydImage();
 	}
 
 	Graphics::MacWidget *widget = new Graphics::MacWidget(g_director->getCurrentWindow(), bbox.left, bbox.top, bbox.width(), bbox.height(), g_director->_wm, false);
@@ -285,15 +285,17 @@ void BitmapCastMember::ditherImage() {
 		return;
 
 	int bpp = _img->getSurface()->format.bytesPerPixel;
+	int w = _initialRect.width();
+	int h = _initialRect.height();
 
 	_ditheredImg = new Graphics::Surface;
-	_ditheredImg->create(_initialRect.width(), _initialRect.height(), g_director->_pixelformat);
+	_ditheredImg->create(w, h, g_director->_pixelformat);
 
-	for (int y = 0; y < _initialRect.height(); y++) {
+	for (int y = 0; y < h; y++) {
 		const byte *src = (const byte *)_img->getSurface()->getBasePtr(0, y);
 		byte *dst = (byte *)_ditheredImg->getBasePtr(0, y);
 
-		for (int x = 0; x < _initialRect.width(); x++) {
+		for (int x = 0; x < w; x++) {
 			uint32 color;
 
 			switch (bpp) {
@@ -318,6 +320,89 @@ void BitmapCastMember::ditherImage() {
 	}
 }
 
+static void updatePixel(byte *surf, int x, int y, int w, int h, int qr, int qg, int qb, int qq) {
+	if (x >= w || y >= h)
+		return;
+
+	byte *ptr = &surf[x * 3 + y * w * 3];
+
+	ptr[0] = CLIP(ptr[0] + qr * qq / 16, 0, 255);
+	ptr[1] = CLIP(ptr[1] + qg * qq / 16, 0, 255);
+	ptr[2] = CLIP(ptr[2] + qb * qq / 16, 0, 255);
+}
+
+void BitmapCastMember::ditherFloydImage() {
+	// If palette did not change, do not re-dither
+	if (!_paletteLookup.setPalette(g_director->_wm->getPalette(), g_director->_wm->getPaletteSize()))
+		return;
+
+	int w = _initialRect.width();
+	int h = _initialRect.height();
+
+	byte *tmpSurf = (byte *)malloc(w * h * 3);
+
+	int bpp = _img->getSurface()->format.bytesPerPixel;
+
+	for (int y = 0; y < h; y++) {
+		const byte *src = (const byte *)_img->getSurface()->getBasePtr(0, y);
+		byte *dst = &tmpSurf[y * w * 3];
+
+		for (int x = 0; x < w; x++) {
+			uint32 color;
+
+			switch (bpp) {
+			case 2:
+				color = *((const uint16 *)src);
+				src += 2;
+				break;
+			case 4:
+				color = *((const uint32 *)src);
+				src += 4;
+				break;
+			default:
+				error("BitmapCastMember::ditherImage(): Unsupported bit depth: %d", bpp);
+			}
+
+			byte r, g, b;
+			_img->getSurface()->format.colorToRGB(color, r, g, b);
+
+			dst[0] = r; dst[1] = g; dst[2] = b;
+			dst += 3;
+		}
+	}
+
+	_ditheredImg = new Graphics::Surface;
+	_ditheredImg->create(w, h, g_director->_pixelformat);
+
+	const byte *pal = g_director->_wm->getPalette();
+
+	for (int y = 0; y < h; y++) {
+		const byte *src = &tmpSurf[y * w * 3];
+		byte *dst = (byte *)_ditheredImg->getBasePtr(0, y);
+
+		for (int x = 0; x < w; x++) {
+			byte r = src[0], g = src[1], b = src[2];
+			byte col = _paletteLookup.findBestColor(r, g, b);
+
+			*dst = col;
+
+			int qr = r - pal[col * 3 + 0];
+			int qg = g = pal[col * 3 + 1];
+			int qb = b = pal[col * 3 + 2];
+
+			updatePixel(tmpSurf, x + 1, y,     w, h, qr, qg, qb, 7);
+			updatePixel(tmpSurf, x - 1, y + 1, w, h, qr, qg, qb, 3);
+			updatePixel(tmpSurf, x,     y + 1, w, h, qr, qg, qb, 5);
+			updatePixel(tmpSurf, x + 1, y + 1, w, h, qr, qg, qb, 1);
+
+			src += 3;
+			dst++;
+		}
+	}
+
+	free(tmpSurf);
+}
+
 void BitmapCastMember::createMatte(Common::Rect &bbox) {
 	// Like background trans, but all white pixels NOT ENCLOSED by coloured pixels
 	// are transparent
diff --git a/engines/director/castmember.h b/engines/director/castmember.h
index 5a3c43aa870..7ddc6a8ad91 100644
--- a/engines/director/castmember.h
+++ b/engines/director/castmember.h
@@ -149,6 +149,7 @@ public:
 
 private:
 	void ditherImage();
+	void ditherFloydImage();
 
 	Graphics::PaletteLookup _paletteLookup;
 };




More information about the Scummvm-git-logs mailing list