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

bluegr noreply at scummvm.org
Wed Mar 5 11:37:05 UTC 2025


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

Summary:
b940265816 IMAGE: Use palette class in Cinepak decoder.


Commit: b940265816877845975b914afd223cb78ac56221
    https://github.com/scummvm/scummvm/commit/b940265816877845975b914afd223cb78ac56221
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2025-03-05T13:37:01+02:00

Commit Message:
IMAGE: Use palette class in Cinepak decoder.
The Cinepak decoder had an unweighted euclidean color distance calculation for palette matching. This was moved and rewritten to a color distance method on the palette class.

Changed paths:
    graphics/palette.cpp
    graphics/palette.h
    image/codecs/cinepak.cpp
    image/codecs/cinepak.h


diff --git a/graphics/palette.cpp b/graphics/palette.cpp
index e64baf2edcc..651a539d95b 100644
--- a/graphics/palette.cpp
+++ b/graphics/palette.cpp
@@ -110,6 +110,21 @@ byte Palette::findBestColor(byte cr, byte cg, byte cb, ColorDistanceMethod metho
 
 	switch (method)
 	{
+	case kColorDistanceEuclidean:
+		for (int i = 0; i < _size; i++) {
+			int r = _data[3 * i + 0] - cr;
+			int g = _data[3 * i + 1] - cg;
+			int b = _data[3 * i + 2] - cb;
+			if (r == 0 && g == 0 && b == 0)
+				return i;
+
+			uint32 distSquared =  r * r + g * g + b * b;
+			if (distSquared < min) {
+				bestColor = i;
+				min = distSquared;
+			}
+		}
+	break;
 	case kColorDistanceNaive:
 		for (uint i = 0; i < _size; i++) {
 			int r = _data[3 * i + 0] - cr;
diff --git a/graphics/palette.h b/graphics/palette.h
index ae103c792a5..90e6323e4a1 100644
--- a/graphics/palette.h
+++ b/graphics/palette.h
@@ -27,8 +27,9 @@
 namespace Graphics {
 
 enum ColorDistanceMethod {
-	kColorDistanceNaive,	///< Weighted red 30%, green 50%, blue 20%
-	kColorDistanceRedmean,	///< Common low-cost approximation
+	kColorDistanceEuclidean, ///< Non-Weighted distance
+	kColorDistanceNaive,	 ///< Weighted red 30%, green 50%, blue 20%
+	kColorDistanceRedmean,	 ///< Common low-cost approximation
 };
 
 /**
diff --git a/image/codecs/cinepak.cpp b/image/codecs/cinepak.cpp
index 9920e266dde..b2701bc97a8 100644
--- a/image/codecs/cinepak.cpp
+++ b/image/codecs/cinepak.cpp
@@ -278,12 +278,11 @@ void decodeVectorsTmpl(CinepakFrame &frame, const byte *clipTable, Common::Seeka
 
 } // End of anonymous namespace
 
-CinepakDecoder::CinepakDecoder(int bitsPerPixel) : Codec(), _bitsPerPixel(bitsPerPixel) {
+CinepakDecoder::CinepakDecoder(int bitsPerPixel) : Codec(), _bitsPerPixel(bitsPerPixel), _ditherPalette(0) {
 	_curFrame.surface = 0;
 	_curFrame.strips = 0;
 	_y = 0;
 	_colorMap = 0;
-	_ditherPalette = 0;
 	_ditherType = kDitherTypeUnknown;
 
 	if (bitsPerPixel == 8) {
@@ -322,7 +321,6 @@ CinepakDecoder::~CinepakDecoder() {
 	delete[] _clipTableBuf;
 
 	delete[] _colorMap;
-	delete[] _ditherPalette;
 }
 
 const Graphics::Surface *CinepakDecoder::decodeFrame(Common::SeekableReadStream &stream) {
@@ -412,7 +410,7 @@ const Graphics::Surface *CinepakDecoder::decodeFrame(Common::SeekableReadStream
 			case 0x30:
 			case 0x31:
 			case 0x32:
-				if (_ditherPalette)
+				if (_ditherPalette.size() > 0)
 					ditherVectors(stream, i, chunkID, chunkSize);
 				else if (_bitsPerPixel == 8)
 					decodeVectors8(stream, i, chunkID, chunkSize);
@@ -666,10 +664,9 @@ void CinepakDecoder::setDither(DitherType type, const byte *palette) {
 	assert(canDither(type));
 
 	delete[] _colorMap;
-	delete[] _ditherPalette;
 
-	_ditherPalette = new byte[256 * 3];
-	memcpy(_ditherPalette, palette, 256 * 3);
+	_ditherPalette.resize(256, false);
+	_ditherPalette.set(palette, 0, 256);
 
 	_dirtyPalette = true;
 	_pixelFormat = Graphics::PixelFormat::createFormatCLUT8();
@@ -688,37 +685,11 @@ void CinepakDecoder::setDither(DitherType type, const byte *palette) {
 }
 
 byte CinepakDecoder::findNearestRGB(int index) const {
-	int r = s_defaultPalette[index * 3];
-	int g = s_defaultPalette[index * 3 + 1];
-	int b = s_defaultPalette[index * 3 + 2];
+	byte r = s_defaultPalette[index * 3];
+	byte g = s_defaultPalette[index * 3 + 1];
+	byte b = s_defaultPalette[index * 3 + 2];
 
-	byte result = 0;
-	int diff = 0x7FFFFFFF;
-
-	for (int i = 0; i < 256; i++) {
-		int bDiff = b - (int)_ditherPalette[i * 3 + 2];
-		int curDiffB = diff - (bDiff * bDiff);
-
-		if (curDiffB > 0) {
-			int gDiff = g - (int)_ditherPalette[i * 3 + 1];
-			int curDiffG = curDiffB - (gDiff * gDiff);
-
-			if (curDiffG > 0) {
-				int rDiff = r - (int)_ditherPalette[i * 3];
-				int curDiffR = curDiffG - (rDiff * rDiff);
-
-				if (curDiffR > 0) {
-					diff -= curDiffR;
-					result = i;
-
-					if (diff == 0)
-						break;
-				}
-			}
-		}
-	}
-
-	return result;
+	return _ditherPalette.findBestColor(r, g, b, Graphics::kColorDistanceEuclidean);
 }
 
 void CinepakDecoder::ditherVectors(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize) {
diff --git a/image/codecs/cinepak.h b/image/codecs/cinepak.h
index bcad3eb24a2..65060274021 100644
--- a/image/codecs/cinepak.h
+++ b/image/codecs/cinepak.h
@@ -25,6 +25,7 @@
 #include "common/scummsys.h"
 #include "common/rect.h"
 #include "graphics/pixelformat.h"
+#include "graphics/palette.h"
 
 #include "image/codecs/codec.h"
 
@@ -77,7 +78,7 @@ public:
 	bool setOutputPixelFormat(const Graphics::PixelFormat &format) override;
 
 	bool containsPalette() const override { return _ditherPalette != 0; }
-	const byte *getPalette() override { _dirtyPalette = false; return _ditherPalette; }
+	const byte *getPalette() override { _dirtyPalette = false; return _ditherPalette.data(); }
 	bool hasDirtyPalette() const override { return _dirtyPalette; }
 	bool canDither(DitherType type) const override;
 	void setDither(DitherType type, const byte *palette) override;
@@ -89,7 +90,7 @@ private:
 	Graphics::PixelFormat _pixelFormat;
 	byte *_clipTable, *_clipTableBuf;
 
-	byte *_ditherPalette;
+	Graphics::Palette _ditherPalette;
 	bool _dirtyPalette;
 	byte *_colorMap;
 	DitherType _ditherType;




More information about the Scummvm-git-logs mailing list