include/vcl/BitmapReadAccess.hxx |   19 ++++---
 vcl/source/bitmap/bitmap.cxx     |  105 ++++++++++++++++++++-------------------
 vcl/source/bitmap/floyd.hxx      |   58 +++++++--------------
 3 files changed, 85 insertions(+), 97 deletions(-)

New commits:
commit 390e8ad3e96d1ab4494976d7ba6f0d0c728090ee
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Wed Oct 4 15:11:45 2023 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Thu Oct 5 12:56:59 2023 +0200

    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.kagan...@collabora.com>

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: */
commit b34fceb3caea3de53abfc1fc2cb4a5a15af5fd6f
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Wed Oct 4 14:51:37 2023 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Thu Oct 5 12:56:55 2023 +0200

    Add BitmapReadAccess::GetColorFromData
    
    Change-Id: Ie7eb0770dc6c5feaa7b4835bdaebfe688a3a381f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157580
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/include/vcl/BitmapReadAccess.hxx b/include/vcl/BitmapReadAccess.hxx
index c2d4c8f43c42..0d12bcae9dd6 100644
--- a/include/vcl/BitmapReadAccess.hxx
+++ b/include/vcl/BitmapReadAccess.hxx
@@ -79,22 +79,25 @@ public:
     {
         assert(mpBuffer && "Access is not valid!");
         assert(nX < mpBuffer->mnWidth && "x-coordinate out of range!");
-        assert(nY < mpBuffer->mnHeight && "y-coordinate out of range!");
 
-        return mFncGetPixel(GetScanline(nY), nX, maColorMask);
+        return GetPixelFromData(GetScanline(nY), nX);
     }
 
     BitmapColor GetPixel(const Point& point) const { return 
GetPixel(point.Y(), point.X()); }
 
-    BitmapColor GetColor(tools::Long nY, tools::Long nX) const
+    BitmapColor GetColorFromData(sal_uInt8* pData, tools::Long nX) const
     {
         if (HasPalette())
-        {
-            const BitmapBuffer* pBuffer = mpBuffer;
-            return pBuffer->maPalette[GetPixelIndex(nY, nX)];
-        }
+            return GetPaletteColor(GetIndexFromData(pData, nX));
         else
-            return GetPixel(nY, nX);
+            return GetPixelFromData(pData, nX);
+    }
+
+    BitmapColor GetColor(tools::Long nY, tools::Long nX) const
+    {
+        assert(mpBuffer && "Access is not valid!");
+        assert(nX < mpBuffer->mnWidth && "x-coordinate out of range!");
+        return GetColorFromData(GetScanline(nY), nX);
     }
 
     BitmapColor GetColor(const Point& point) const { return 
GetColor(point.Y(), point.X()); }

Reply via email to