summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2023-10-04 15:11:45 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2023-10-05 12:56:59 +0200
commit390e8ad3e96d1ab4494976d7ba6f0d0c728090ee (patch)
treed9dde57013509fb96a5994495bfa81f9fea74a37 /vcl
parentb34fceb3caea3de53abfc1fc2cb4a5a15af5fd6f (diff)
Simplify Bitmap::Dither
... and drop some macros used there. Change-Id: I3ee8f3f4f2658904d32e6b63c0be6483783b22b4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157581 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/source/bitmap/bitmap.cxx105
-rw-r--r--vcl/source/bitmap/floyd.hxx58
2 files changed, 74 insertions, 89 deletions
diff --git a/vcl/source/bitmap/bitmap.cxx b/vcl/source/bitmap/bitmap.cxx
index 1759787d05fc..80bff80e05f4 100644
--- a/vcl/source/bitmap/bitmap.cxx
+++ b/vcl/source/bitmap/bitmap.cxx
@@ -1393,20 +1393,16 @@ void Bitmap::AdaptBitCount(Bitmap& rNew) const
}
}
-static sal_Int32* shiftColor(sal_Int32* pColorArray, BitmapColor const& rColor)
+static void shiftColors(sal_Int32* pColorArray, const Bitmap::ScopedReadAccess& pReadAcc)
{
- *pColorArray++ = static_cast<sal_Int32>(rColor.GetBlue()) << 12;
- *pColorArray++ = static_cast<sal_Int32>(rColor.GetGreen()) << 12;
- *pColorArray++ = static_cast<sal_Int32>(rColor.GetRed()) << 12;
- return pColorArray;
-}
-static BitmapColor getColor(const BitmapReadAccess *pReadAcc, tools::Long nZ)
-{
- Scanline pScanlineRead = pReadAcc->GetScanline(0);
- if (pReadAcc->HasPalette())
- return pReadAcc->GetPaletteColor(pReadAcc->GetIndexFromData(pScanlineRead, nZ));
- else
- return pReadAcc->GetPixelFromData(pScanlineRead, nZ);
+ Scanline pScanlineRead = pReadAcc->GetScanline(0); // Why always 0?
+ for (tools::Long n = 0; n < pReadAcc->Width(); ++n)
+ {
+ const BitmapColor& rColor = pReadAcc->GetColorFromData(pScanlineRead, n);
+ *pColorArray++ = static_cast<sal_Int32>(rColor.GetBlue()) << 12;
+ *pColorArray++ = static_cast<sal_Int32>(rColor.GetGreen()) << 12;
+ *pColorArray++ = static_cast<sal_Int32>(rColor.GetRed()) << 12;
+ }
}
bool Bitmap::Dither()
@@ -1432,51 +1428,60 @@ bool Bitmap::Dither()
std::unique_ptr<sal_Int32[]> p2(new sal_Int32[ nW ]);
sal_Int32* p1T = p1.get();
sal_Int32* p2T = p2.get();
- sal_Int32* pTmp = p2T;
- for (tools::Long nZ = 0; nZ < nWidth; nZ++)
+ shiftColors(p2T, pReadAcc);
+ for( tools::Long nYAcc = 0; nYAcc < nHeight; nYAcc++ )
{
- pTmp = shiftColor(pTmp, getColor(pReadAcc.get(), nZ));
- }
- tools::Long nRErr, nGErr, nBErr;
- tools::Long nRC, nGC, nBC;
- for( tools::Long nY = 1, nYAcc = 0; nY <= nHeight; nY++, nYAcc++ )
- {
- pTmp = p1T;
- p1T = p2T;
- p2T = pTmp;
- if (nY < nHeight)
+ std::swap(p1T, p2T);
+ if (nYAcc < nHeight - 1)
+ shiftColors(p2T, pReadAcc);
+
+ auto CalcError = [](tools::Long n)
{
- for (tools::Long nZ = 0; nZ < nWidth; nZ++)
- {
- pTmp = shiftColor(pTmp, getColor(pReadAcc.get(), nZ));
- }
- }
- // Examine first Pixel separately
- tools::Long nX = 0;
- tools::Long nTemp;
- CALC_ERRORS;
- CALC_TABLES7;
- nX -= 5;
- CALC_TABLES5;
+ n = std::clamp<tools::Long>(n >> 12, 0, 255);
+ return std::pair(FloydErrMap[n], FloydMap[n]);
+ };
+
+ auto CalcErrors = [&](tools::Long n)
+ { return std::tuple_cat(CalcError(p1T[n]), CalcError(p1T[n + 1]), CalcError(p1T[n + 2])); };
+
+ auto CalcT = [](sal_Int32* dst, const int* src, int b, int g, int r)
+ {
+ dst[0] += src[b];
+ dst[1] += src[g];
+ dst[2] += src[r];
+ };
+
+ auto Calc1 = [&](int x, int b, int g, int r) { CalcT(p2T + x + 3, FloydError1, b, g, r); };
+ auto Calc3 = [&](int x, int b, int g, int r) { CalcT(p2T + x - 3, FloydError3, b, g, r); };
+ auto Calc5 = [&](int x, int b, int g, int r) { CalcT(p2T + x, FloydError5, b, g, r); };
+ auto Calc7 = [&](int x, int b, int g, int r) { CalcT(p1T + x + 3, FloydError7, b, g, r); };
+
Scanline pScanline = pWriteAcc->GetScanline(nYAcc);
- pWriteAcc->SetPixelOnData( pScanline, 0, BitmapColor(static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ])) );
+ // Examine first Pixel separately
+ {
+ auto [nBErr, nBC, nGErr, nGC, nRErr, nRC] = CalcErrors(0);
+ Calc1(0, nBErr, nGErr, nRErr);
+ Calc5(0, nBErr, nGErr, nRErr);
+ Calc7(0, nBErr, nGErr, nRErr);
+ pWriteAcc->SetPixelOnData( pScanline, 0, BitmapColor(static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ])) );
+ }
// Get middle Pixels using a loop
- tools::Long nXAcc;
- for ( nX = 3, nXAcc = 1; nX < nW2; nXAcc++ )
+ for ( tools::Long nX = 3, nXAcc = 1; nX < nW2; nX += 3, nXAcc++ )
{
- CALC_ERRORS;
- CALC_TABLES7;
- nX -= 8;
- CALC_TABLES3;
- CALC_TABLES5;
+ auto [nBErr, nBC, nGErr, nGC, nRErr, nRC] = CalcErrors(nX);
+ Calc1(nX, nBErr, nGErr, nRErr);
+ Calc3(nX, nBErr, nGErr, nRErr);
+ Calc5(nX, nBErr, nGErr, nRErr);
+ Calc7(nX, nBErr, nGErr, nRErr);
pWriteAcc->SetPixelOnData( pScanline, nXAcc, BitmapColor(static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ])) );
}
// Treat last Pixel separately
- CALC_ERRORS;
- nX -= 5;
- CALC_TABLES3;
- CALC_TABLES5;
- pWriteAcc->SetPixelOnData( pScanline, nWidth1, BitmapColor(static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ])) );
+ {
+ auto [nBErr, nBC, nGErr, nGC, nRErr, nRC] = CalcErrors(nW2);
+ Calc3(nW2, nBErr, nGErr, nRErr);
+ Calc5(nW2, nBErr, nGErr, nRErr);
+ pWriteAcc->SetPixelOnData( pScanline, nWidth1, BitmapColor(static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ])) );
+ }
}
pReadAcc.reset();
pWriteAcc.reset();
diff --git a/vcl/source/bitmap/floyd.hxx b/vcl/source/bitmap/floyd.hxx
index 0617786a3918..b5f26fb7a6c6 100644
--- a/vcl/source/bitmap/floyd.hxx
+++ b/vcl/source/bitmap/floyd.hxx
@@ -19,35 +19,6 @@
#pragma once
-#define CALC_ERRORS \
- nTemp = p1T[nX++] >> 12; \
- nBErr = MinMax( nTemp, 0, 255 ); \
- nBErr = nBErr - FloydIndexMap[ nBC = FloydMap[nBErr] ]; \
- nTemp = p1T[nX++] >> 12; \
- nGErr = MinMax( nTemp, 0, 255 ); \
- nGErr = nGErr - FloydIndexMap[ nGC = FloydMap[nGErr] ]; \
- nTemp = p1T[nX] >> 12; \
- nRErr = MinMax( nTemp, 0, 255 ); \
- nRErr = nRErr - FloydIndexMap[ nRC = FloydMap[nRErr] ];
-
-#define CALC_TABLES3 \
- p2T[nX++] += FloydError3[nBErr]; \
- p2T[nX++] += FloydError3[nGErr]; \
- p2T[nX++] += FloydError3[nRErr];
-
-#define CALC_TABLES5 \
- p2T[nX++] += FloydError5[nBErr]; \
- p2T[nX++] += FloydError5[nGErr]; \
- p2T[nX++] += FloydError5[nRErr];
-
-#define CALC_TABLES7 \
- p1T[++nX] += FloydError7[nBErr]; \
- p2T[nX++] += FloydError1[nBErr]; \
- p1T[nX] += FloydError7[nGErr]; \
- p2T[nX++] += FloydError1[nGErr]; \
- p1T[nX] += FloydError7[nRErr]; \
- p2T[nX] += FloydError1[nRErr];
-
const extern sal_uLong nVCLRLut[ 6 ] = { 16, 17, 18, 19, 20, 21 };
const extern sal_uLong nVCLGLut[ 6 ] = { 0, 6, 12, 18, 24, 30 };
const extern sal_uLong nVCLBLut[ 6 ] = { 0, 36, 72, 108, 144, 180 };
@@ -116,7 +87,7 @@ const extern sal_uLong nVCLLut[ 256 ] =
318928,320214,321500,322786,324072,325358,326644,327930
};
-const tools::Long FloydMap[256] =
+const int FloydMap[256] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
@@ -136,7 +107,21 @@ const tools::Long FloydMap[256] =
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
};
-const tools::Long FloydError1[61] =
+constexpr int FloydErrMap[256]
+ = { 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };
+
+constexpr int FloydError1[61] =
{
-7680, -7424, -7168, -6912, -6656, -6400, -6144,
-5888, -5632, -5376, -5120, -4864, -4608, -4352,
@@ -148,7 +133,7 @@ const tools::Long FloydError1[61] =
5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680
};
-const tools::Long FloydError3[61] =
+constexpr int FloydError3[61] =
{
-23040, -22272, -21504, -20736, -19968, -19200,
-18432, -17664, -16896, -16128, -15360, -14592,
@@ -161,7 +146,7 @@ const tools::Long FloydError3[61] =
19200, 19968, 20736, 21504, 22272, 23040
};
-const tools::Long FloydError5[61] =
+constexpr int FloydError5[61] =
{
-38400, -37120, -35840, -34560, -33280, -32000,
-30720, -29440, -28160, -26880, -25600, -24320,
@@ -175,7 +160,7 @@ const tools::Long FloydError5[61] =
38400
};
-const tools::Long FloydError7[61] =
+constexpr int FloydError7[61] =
{
-53760, -51968, -50176, -48384, -46592, -44800,
-43008, -41216, -39424, -37632, -35840, -34048,
@@ -189,9 +174,4 @@ const tools::Long FloydError7[61] =
53760
};
-const tools::Long FloydIndexMap[6] =
-{
- -30, 21, 72, 123, 174, 225
-};
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */