[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