[Libreoffice-commits] core.git: 2 commits - vcl/inc vcl/qa vcl/source
Tomaž Vajngerl (via logerrit)
logerrit at kemper.freedesktop.org
Sun Apr 14 12:20:17 UTC 2019
vcl/inc/bitmap/Octree.hxx | 60 +++-----------
vcl/inc/bitmap/impoctree.hxx | 48 +++++------
vcl/qa/cppunit/BitmapTest.cxx | 51 +++++++++++
vcl/source/bitmap/Octree.cxx | 179 ++++++++++++++++++++++++------------------
4 files changed, 194 insertions(+), 144 deletions(-)
New commits:
commit eb772683513f4f2b6c8e6404c29b8e477ffc7fad
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sun Apr 14 16:26:29 2019 +0900
Commit: Tomaž Vajngerl <quikee at gmail.com>
CommitDate: Sun Apr 14 14:19:34 2019 +0200
Octree: more clean-up, avoid memset, prefix member vars
Change-Id: I79ec1d0176f523d16c53220de9b0a0d9819729ea
Reviewed-on: https://gerrit.libreoffice.org/70729
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
diff --git a/vcl/inc/bitmap/Octree.hxx b/vcl/inc/bitmap/Octree.hxx
index 3e54826a9313..3336c115106f 100644
--- a/vcl/inc/bitmap/Octree.hxx
+++ b/vcl/inc/bitmap/Octree.hxx
@@ -23,9 +23,6 @@
#include <vcl/salbtype.hxx>
#include <vcl/dllapi.h>
-#define OCTREE_BITS 5
-#define OCTREE_BITS_1 10
-
struct OctreeNode
{
sal_uLong nCount;
@@ -48,51 +45,33 @@ private:
void CreatePalette(OctreeNode* pNode);
void GetPalIndex(OctreeNode* pNode);
- SAL_DLLPRIVATE void ImplDeleteOctree(OctreeNode** ppNode);
- SAL_DLLPRIVATE void ImplAdd(OctreeNode** ppNode);
- SAL_DLLPRIVATE void ImplReduce();
+ SAL_DLLPRIVATE void deleteOctree(OctreeNode** ppNode);
+ SAL_DLLPRIVATE void add(OctreeNode** ppNode);
+ SAL_DLLPRIVATE void reduce();
- BitmapPalette aPal;
- sal_uLong nLeafCount;
- sal_uLong nLevel;
+ BitmapPalette maPalette;
+ sal_uLong mnLeafCount;
+ sal_uLong mnLevel;
OctreeNode* pTree;
- OctreeNode* pReduce[OCTREE_BITS + 1];
- BitmapColor const* pColor;
- std::unique_ptr<ImpNodeCache> pNodeCache;
- const BitmapReadAccess* pAcc;
- sal_uInt16 nPalIndex;
+ std::vector<OctreeNode*> mpReduce;
+ BitmapColor const* mpColor;
+ std::unique_ptr<ImpNodeCache> mpNodeCache;
+ const BitmapReadAccess* mpAccess;
+ sal_uInt16 mnPalIndex;
public:
Octree(const BitmapReadAccess& rReadAcc, sal_uLong nColors);
~Octree();
- inline const BitmapPalette& GetPalette();
- inline sal_uInt16 GetBestPaletteIndex(const BitmapColor& rColor);
+ const BitmapPalette& GetPalette();
+ sal_uInt16 GetBestPaletteIndex(const BitmapColor& rColor);
};
-inline const BitmapPalette& Octree::GetPalette()
-{
- aPal.SetEntryCount(static_cast<sal_uInt16>(nLeafCount));
- nPalIndex = 0;
- CreatePalette(pTree);
- return aPal;
-}
-
-inline sal_uInt16 Octree::GetBestPaletteIndex(const BitmapColor& rColor)
-{
- pColor = &rColor;
- nPalIndex = 65535;
- nLevel = 0;
- GetPalIndex(pTree);
- return nPalIndex;
-}
-
class VCL_PLUGIN_PUBLIC InverseColorMap
{
private:
- std::unique_ptr<sal_uInt8[]> pBuffer;
- std::unique_ptr<sal_uInt8[]> pMap;
- static constexpr sal_uLong gnBits = 8 - OCTREE_BITS;
+ std::vector<sal_uInt8> mpBuffer;
+ std::vector<sal_uInt8> mpMap;
SAL_DLLPRIVATE void ImplCreateBuffers(const sal_uLong nMax);
@@ -100,16 +79,9 @@ public:
explicit InverseColorMap(const BitmapPalette& rPal);
~InverseColorMap();
- inline sal_uInt16 GetBestPaletteIndex(const BitmapColor& rColor);
+ sal_uInt16 GetBestPaletteIndex(const BitmapColor& rColor);
};
-inline sal_uInt16 InverseColorMap::GetBestPaletteIndex(const BitmapColor& rColor)
-{
- return pMap[((static_cast<sal_uLong>(rColor.GetRed()) >> gnBits) << OCTREE_BITS_1)
- | ((static_cast<sal_uLong>(rColor.GetGreen()) >> gnBits) << OCTREE_BITS)
- | (static_cast<sal_uLong>(rColor.GetBlue()) >> gnBits)];
-}
-
#endif // INCLUDED_VCL_INC_OCTREE_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/bitmap/impoctree.hxx b/vcl/inc/bitmap/impoctree.hxx
index 0ade7b7bcc3b..727551123c5c 100644
--- a/vcl/inc/bitmap/impoctree.hxx
+++ b/vcl/inc/bitmap/impoctree.hxx
@@ -37,9 +37,9 @@ public:
}
ImpErrorQuad(const BitmapColor& rColor)
- : nRed(static_cast<long>(rColor.GetRed()) << 5)
- , nGreen(static_cast<long>(rColor.GetGreen()) << 5)
- , nBlue(static_cast<long>(rColor.GetBlue()) << 5)
+ : nRed(long(rColor.GetRed()) << 5)
+ , nGreen(long(rColor.GetGreen()) << 5)
+ , nBlue(long(rColor.GetBlue()) << 5)
{
}
@@ -56,54 +56,52 @@ public:
inline void ImpErrorQuad::operator=(const BitmapColor& rColor)
{
- nRed = static_cast<long>(rColor.GetRed()) << 5;
- nGreen = static_cast<long>(rColor.GetGreen()) << 5;
- nBlue = static_cast<long>(rColor.GetBlue()) << 5;
+ nRed = long(rColor.GetRed()) << 5;
+ nGreen = long(rColor.GetGreen()) << 5;
+ nBlue = long(rColor.GetBlue()) << 5;
}
inline ImpErrorQuad& ImpErrorQuad::operator-=(const BitmapColor& rColor)
{
- nRed -= (static_cast<long>(rColor.GetRed()) << 5);
- nGreen -= (static_cast<long>(rColor.GetGreen()) << 5);
- nBlue -= (static_cast<long>(rColor.GetBlue()) << 5);
+ nRed -= long(rColor.GetRed()) << 5;
+ nGreen -= long(rColor.GetGreen()) << 5;
+ nBlue -= long(rColor.GetBlue()) << 5;
return *this;
}
inline void ImpErrorQuad::ImplAddColorError1(const ImpErrorQuad& rErrQuad)
{
- nRed += (rErrQuad.nRed >> 4);
- nGreen += (rErrQuad.nGreen >> 4);
- nBlue += (rErrQuad.nBlue >> 4);
+ nRed += rErrQuad.nRed >> 4;
+ nGreen += rErrQuad.nGreen >> 4;
+ nBlue += rErrQuad.nBlue >> 4;
}
inline void ImpErrorQuad::ImplAddColorError3(const ImpErrorQuad& rErrQuad)
{
- nRed += (rErrQuad.nRed * 3L >> 4);
- nGreen += (rErrQuad.nGreen * 3L >> 4);
- nBlue += (rErrQuad.nBlue * 3L >> 4);
+ nRed += rErrQuad.nRed * 3L >> 4;
+ nGreen += rErrQuad.nGreen * 3L >> 4;
+ nBlue += rErrQuad.nBlue * 3L >> 4;
}
inline void ImpErrorQuad::ImplAddColorError5(const ImpErrorQuad& rErrQuad)
{
- nRed += (rErrQuad.nRed * 5L >> 4);
- nGreen += (rErrQuad.nGreen * 5L >> 4);
- nBlue += (rErrQuad.nBlue * 5L >> 4);
+ nRed += rErrQuad.nRed * 5L >> 4;
+ nGreen += rErrQuad.nGreen * 5L >> 4;
+ nBlue += rErrQuad.nBlue * 5L >> 4;
}
inline void ImpErrorQuad::ImplAddColorError7(const ImpErrorQuad& rErrQuad)
{
- nRed += (rErrQuad.nRed * 7L >> 4);
- nGreen += (rErrQuad.nGreen * 7L >> 4);
- nBlue += (rErrQuad.nBlue * 7L >> 4);
+ nRed += rErrQuad.nRed * 7L >> 4;
+ nGreen += rErrQuad.nGreen * 7L >> 4;
+ nBlue += rErrQuad.nBlue * 7L >> 4;
}
inline BitmapColor ImpErrorQuad::ImplGetColor()
{
- return BitmapColor(
- static_cast<sal_uInt8>((nRed < 0 ? 0L : nRed > 8160 ? 8160L : nRed) >> 5),
- static_cast<sal_uInt8>((nGreen < 0 ? 0L : nGreen > 8160 ? 8160L : nGreen) >> 5),
- static_cast<sal_uInt8>((nBlue < 0 ? 0L : nBlue > 8160 ? 8160L : nBlue) >> 5));
+ return BitmapColor(std::clamp(nRed, 0L, 8160L) >> 5, std::clamp(nGreen, 0L, 8160L) >> 5,
+ std::clamp(nBlue, 0L, 8160L) >> 5);
}
class ImpNodeCache
diff --git a/vcl/source/bitmap/Octree.cxx b/vcl/source/bitmap/Octree.cxx
index 6650e52d0692..5f291e6ab8fb 100644
--- a/vcl/source/bitmap/Octree.cxx
+++ b/vcl/source/bitmap/Octree.cxx
@@ -25,7 +25,14 @@
#include <bitmap/Octree.hxx>
#include <bitmap/impoctree.hxx>
-static const sal_uInt8 pImplMask[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
+namespace
+{
+constexpr size_t OCTREE_BITS = 5;
+constexpr size_t OCTREE_BITS_1 = 10;
+
+constexpr sal_uLong gnBits = 8 - OCTREE_BITS;
+
+} // end anonymous namespace
ImpNodeCache::ImpNodeCache(const sal_uLong nInitSize)
: pActNode(nullptr)
@@ -53,35 +60,35 @@ ImpNodeCache::~ImpNodeCache()
}
Octree::Octree(const BitmapReadAccess& rReadAcc, sal_uLong nColors)
- : nLeafCount(0)
- , nLevel(0)
+ : mnLeafCount(0)
+ , mnLevel(0)
, pTree(nullptr)
- , pColor(nullptr)
- , pAcc(&rReadAcc)
- , nPalIndex(0)
+ , mpReduce(OCTREE_BITS + 1, nullptr)
+ , mpColor(nullptr)
+ , mpNodeCache(std::make_unique<ImpNodeCache>(nColors))
+ , mpAccess(&rReadAcc)
+ , mnPalIndex(0)
{
sal_uLong nMax(nColors);
- pNodeCache.reset(new ImpNodeCache(nColors));
- memset(pReduce, 0, (OCTREE_BITS + 1) * sizeof(OctreeNode*));
- if (!!*pAcc)
+ if (!!*mpAccess)
{
- const long nWidth = pAcc->Width();
- const long nHeight = pAcc->Height();
+ const long nWidth = mpAccess->Width();
+ const long nHeight = mpAccess->Height();
- if (pAcc->HasPalette())
+ if (mpAccess->HasPalette())
{
for (long nY = 0; nY < nHeight; nY++)
{
- Scanline pScanline = pAcc->GetScanline(nY);
+ Scanline pScanline = mpAccess->GetScanline(nY);
for (long nX = 0; nX < nWidth; nX++)
{
- pColor = &pAcc->GetPaletteColor(pAcc->GetIndexFromData(pScanline, nX));
- nLevel = 0;
- ImplAdd(&pTree);
+ mpColor = &mpAccess->GetPaletteColor(mpAccess->GetIndexFromData(pScanline, nX));
+ mnLevel = 0;
+ add(&pTree);
- while (nLeafCount > nMax)
- ImplReduce();
+ while (mnLeafCount > nMax)
+ reduce();
}
}
}
@@ -89,97 +96,94 @@ Octree::Octree(const BitmapReadAccess& rReadAcc, sal_uLong nColors)
{
BitmapColor aColor;
- pColor = &aColor;
+ mpColor = &aColor;
for (long nY = 0; nY < nHeight; nY++)
{
- Scanline pScanline = pAcc->GetScanline(nY);
+ Scanline pScanline = mpAccess->GetScanline(nY);
for (long nX = 0; nX < nWidth; nX++)
{
- aColor = pAcc->GetPixelFromData(pScanline, nX);
- nLevel = 0;
- ImplAdd(&pTree);
+ aColor = mpAccess->GetPixelFromData(pScanline, nX);
+ mnLevel = 0;
+ add(&pTree);
- while (nLeafCount > nMax)
- ImplReduce();
+ while (mnLeafCount > nMax)
+ reduce();
}
}
}
}
}
-Octree::~Octree()
-{
- ImplDeleteOctree(&pTree);
- pNodeCache.reset();
-}
+Octree::~Octree() { deleteOctree(&pTree); }
-void Octree::ImplDeleteOctree(OctreeNode** ppNode)
+void Octree::deleteOctree(OctreeNode** ppNode)
{
for (OctreeNode* i : (*ppNode)->pChild)
{
if (i)
- ImplDeleteOctree(&i);
+ deleteOctree(&i);
}
- pNodeCache->ImplReleaseNode(*ppNode);
+ mpNodeCache->ImplReleaseNode(*ppNode);
*ppNode = nullptr;
}
-void Octree::ImplAdd(OctreeNode** ppNode)
+void Octree::add(OctreeNode** ppNode)
{
// possibly generate new nodes
if (!*ppNode)
{
- *ppNode = pNodeCache->ImplGetFreeNode();
- (*ppNode)->bLeaf = (OCTREE_BITS == nLevel);
+ *ppNode = mpNodeCache->ImplGetFreeNode();
+ (*ppNode)->bLeaf = (OCTREE_BITS == mnLevel);
if ((*ppNode)->bLeaf)
- nLeafCount++;
+ mnLeafCount++;
else
{
- (*ppNode)->pNext = pReduce[nLevel];
- pReduce[nLevel] = *ppNode;
+ (*ppNode)->pNext = mpReduce[mnLevel];
+ mpReduce[mnLevel] = *ppNode;
}
}
if ((*ppNode)->bLeaf)
{
(*ppNode)->nCount++;
- (*ppNode)->nRed += pColor->GetRed();
- (*ppNode)->nGreen += pColor->GetGreen();
- (*ppNode)->nBlue += pColor->GetBlue();
+ (*ppNode)->nRed += mpColor->GetRed();
+ (*ppNode)->nGreen += mpColor->GetGreen();
+ (*ppNode)->nBlue += mpColor->GetBlue();
}
else
{
- const sal_uLong nShift = 7 - nLevel;
- const sal_uInt8 cMask = pImplMask[nLevel];
- const sal_uLong nIndex = (((pColor->GetRed() & cMask) >> nShift) << 2)
- | (((pColor->GetGreen() & cMask) >> nShift) << 1)
- | ((pColor->GetBlue() & cMask) >> nShift);
-
- nLevel++;
- ImplAdd(&(*ppNode)->pChild[nIndex]);
+ const sal_uLong nShift = 7 - mnLevel;
+ const sal_uInt8 cMask = 0x80 >> mnLevel;
+ const sal_uLong nIndex = (((mpColor->GetRed() & cMask) >> nShift) << 2)
+ | (((mpColor->GetGreen() & cMask) >> nShift) << 1)
+ | ((mpColor->GetBlue() & cMask) >> nShift);
+
+ mnLevel++;
+ add(&(*ppNode)->pChild[nIndex]);
}
}
-void Octree::ImplReduce()
+void Octree::reduce()
{
- sal_uLong i;
OctreeNode* pNode;
sal_uLong nRedSum = 0;
sal_uLong nGreenSum = 0;
sal_uLong nBlueSum = 0;
sal_uLong nChildren = 0;
- for (i = OCTREE_BITS - 1; i && !pReduce[i]; i--)
+ sal_uLong nIndex = OCTREE_BITS - 1;
+ while (nIndex > 0 && !mpReduce[nIndex])
{
+ nIndex--;
}
- pNode = pReduce[i];
- pReduce[i] = pNode->pNext;
+ pNode = mpReduce[nIndex];
+ mpReduce[nIndex] = pNode->pNext;
- for (i = 0; i < 8; i++)
+ for (sal_uLong i = 0; i < 8; i++)
{
if (pNode->pChild[i])
{
@@ -190,7 +194,7 @@ void Octree::ImplReduce()
nBlueSum += pChild->nBlue;
pNode->nCount += pChild->nCount;
- pNodeCache->ImplReleaseNode(pNode->pChild[i]);
+ mpNodeCache->ImplReleaseNode(pNode->pChild[i]);
pNode->pChild[i] = nullptr;
nChildren++;
}
@@ -200,43 +204,64 @@ void Octree::ImplReduce()
pNode->nRed = nRedSum;
pNode->nGreen = nGreenSum;
pNode->nBlue = nBlueSum;
- nLeafCount -= --nChildren;
+ mnLeafCount -= --nChildren;
}
void Octree::CreatePalette(OctreeNode* pNode)
{
if (pNode->bLeaf)
{
- pNode->nPalIndex = nPalIndex;
- aPal[nPalIndex++] = BitmapColor(
- static_cast<sal_uInt8>(static_cast<double>(pNode->nRed) / pNode->nCount),
- static_cast<sal_uInt8>(static_cast<double>(pNode->nGreen) / pNode->nCount),
- static_cast<sal_uInt8>(static_cast<double>(pNode->nBlue) / pNode->nCount));
+ pNode->nPalIndex = mnPalIndex;
+ maPalette[mnPalIndex++] = BitmapColor(sal_uInt8(double(pNode->nRed) / pNode->nCount),
+ sal_uInt8(double(pNode->nGreen) / pNode->nCount),
+ sal_uInt8(double(pNode->nBlue) / pNode->nCount));
}
else
+ {
for (OctreeNode* i : pNode->pChild)
{
if (i)
+ {
CreatePalette(i);
+ }
}
+ }
}
void Octree::GetPalIndex(OctreeNode* pNode)
{
if (pNode->bLeaf)
- nPalIndex = pNode->nPalIndex;
+ mnPalIndex = pNode->nPalIndex;
else
{
- const sal_uLong nShift = 7 - nLevel;
- const sal_uInt8 cMask = pImplMask[nLevel++];
- const sal_uLong nIndex = (((pColor->GetRed() & cMask) >> nShift) << 2)
- | (((pColor->GetGreen() & cMask) >> nShift) << 1)
- | ((pColor->GetBlue() & cMask) >> nShift);
+ const sal_uLong nShift = 7 - mnLevel;
+ const sal_uInt8 cMask = 0x80 >> mnLevel;
+ mnLevel++;
+ const sal_uLong nIndex = (((mpColor->GetRed() & cMask) >> nShift) << 2)
+ | (((mpColor->GetGreen() & cMask) >> nShift) << 1)
+ | ((mpColor->GetBlue() & cMask) >> nShift);
GetPalIndex(pNode->pChild[nIndex]);
}
}
+const BitmapPalette& Octree::GetPalette()
+{
+ maPalette.SetEntryCount(sal_uInt16(mnLeafCount));
+ mnPalIndex = 0;
+ CreatePalette(pTree);
+ return maPalette;
+}
+
+sal_uInt16 Octree::GetBestPaletteIndex(const BitmapColor& rColor)
+{
+ mpColor = &rColor;
+ mnPalIndex = 65535;
+ mnLevel = 0;
+ GetPalIndex(pTree);
+ return mnPalIndex;
+}
+
InverseColorMap::InverseColorMap(const BitmapPalette& rPal)
{
const int nColorMax = 1 << OCTREE_BITS;
@@ -266,8 +291,8 @@ InverseColorMap::InverseColorMap(const BitmapPalette& rPal)
const long cginc = (xsqr - (cGreen << gnBits)) << 1;
const long cbinc = (xsqr - (cBlue << gnBits)) << 1;
- sal_uLong* cdp = reinterpret_cast<sal_uLong*>(pBuffer.get());
- sal_uInt8* crgbp = pMap.get();
+ sal_uLong* cdp = reinterpret_cast<sal_uLong*>(mpBuffer.data());
+ sal_uInt8* crgbp = mpMap.data();
for (r = 0, rxx = crinc; r < nColorMax; rdist += rxx, r++, rxx += xsqr2)
{
@@ -292,11 +317,15 @@ void InverseColorMap::ImplCreateBuffers(const sal_uLong nMax)
const sal_uLong nCount = nMax * nMax * nMax;
const sal_uLong nSize = nCount * sizeof(sal_uLong);
- pMap.reset(new sal_uInt8[nCount]);
- memset(pMap.get(), 0x00, nCount);
+ mpMap.resize(nCount, 0x00);
+ mpBuffer.resize(nSize, 0xff);
+}
- pBuffer.reset(new sal_uInt8[nSize]);
- memset(pBuffer.get(), 0xff, nSize);
+sal_uInt16 InverseColorMap::GetBestPaletteIndex(const BitmapColor& rColor)
+{
+ return mpMap[((static_cast<sal_uLong>(rColor.GetRed()) >> gnBits) << OCTREE_BITS_1)
+ | ((static_cast<sal_uLong>(rColor.GetGreen()) >> gnBits) << OCTREE_BITS)
+ | (static_cast<sal_uLong>(rColor.GetBlue()) >> gnBits)];
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 58187ebf61ddba6574f59bc396c327f76fb48967
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sun Apr 14 15:37:05 2019 +0900
Commit: Tomaž Vajngerl <quikee at gmail.com>
CommitDate: Sun Apr 14 14:19:18 2019 +0200
vcl: add a basic Octree test
Change-Id: I4f142586ceedb8f51610139db914845892f65d2c
Reviewed-on: https://gerrit.libreoffice.org/70728
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
diff --git a/vcl/qa/cppunit/BitmapTest.cxx b/vcl/qa/cppunit/BitmapTest.cxx
index 52abfb6c10e5..6dd6053bed18 100644
--- a/vcl/qa/cppunit/BitmapTest.cxx
+++ b/vcl/qa/cppunit/BitmapTest.cxx
@@ -32,6 +32,7 @@
#include <svdata.hxx>
#include <salinst.hxx>
+#include <bitmap/Octree.hxx>
namespace
{
@@ -50,6 +51,7 @@ class BitmapTest : public CppUnit::TestFixture
void testCustom8BitPalette();
void testErase();
void testBitmap32();
+ void testOctree();
CPPUNIT_TEST_SUITE(BitmapTest);
CPPUNIT_TEST(testCreation);
@@ -65,6 +67,7 @@ class BitmapTest : public CppUnit::TestFixture
CPPUNIT_TEST(testCustom8BitPalette);
CPPUNIT_TEST(testErase);
CPPUNIT_TEST(testBitmap32);
+ CPPUNIT_TEST(testOctree);
CPPUNIT_TEST_SUITE_END();
};
@@ -741,6 +744,54 @@ void BitmapTest::testBitmap32()
}
}
+void BitmapTest::testOctree()
+{
+ Size aSize(1000, 100);
+ Bitmap aBitmap(aSize, 24);
+ {
+ BitmapScopedWriteAccess pWriteAccess(aBitmap);
+ for (long y = 0; y < aSize.Height(); ++y)
+ {
+ for (long x = 0; x < aSize.Width(); ++x)
+ {
+ double fPercent = double(x) / double(aSize.Width());
+ pWriteAccess->SetPixel(y, x,
+ BitmapColor(255.0 * fPercent, 64.0 + (128.0 * fPercent),
+ 255.0 - 255.0 * fPercent));
+ }
+ }
+ }
+
+ {
+ // Reduce to 1 color
+ Bitmap::ScopedReadAccess pAccess(aBitmap);
+ Octree aOctree(*pAccess.get(), 1);
+ auto aBitmapPalette = aOctree.GetPalette();
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), aBitmapPalette.GetEntryCount());
+ CPPUNIT_ASSERT_EQUAL(BitmapColor(0x7e, 0x7f, 0x7f), aBitmapPalette[0]);
+ }
+
+ {
+ // Reduce to 4 color
+ Bitmap::ScopedReadAccess pAccess(aBitmap);
+ Octree aOctree(*pAccess.get(), 4);
+ auto aBitmapPalette = aOctree.GetPalette();
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(4), aBitmapPalette.GetEntryCount());
+ CPPUNIT_ASSERT_EQUAL(BitmapColor(0x7f, 0x7f, 0x7f), aBitmapPalette[0]);
+ CPPUNIT_ASSERT_EQUAL(BitmapColor(0x3e, 0x5f, 0xbf), aBitmapPalette[1]);
+ CPPUNIT_ASSERT_EQUAL(BitmapColor(0x7f, 0x80, 0x7f), aBitmapPalette[2]);
+ CPPUNIT_ASSERT_EQUAL(BitmapColor(0xbe, 0x9f, 0x3f), aBitmapPalette[3]);
+ }
+
+ {
+ // Reduce to 256 color
+ Bitmap::ScopedReadAccess pAccess(aBitmap);
+ Octree aOctree(*pAccess.get(), 256);
+ auto aBitmapPalette = aOctree.GetPalette();
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(74), aBitmapPalette.GetEntryCount());
+ }
+}
+
} // namespace
CPPUNIT_TEST_SUITE_REGISTRATION(BitmapTest);
More information about the Libreoffice-commits
mailing list