[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