diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2023-10-04 15:11:45 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2023-10-05 12:56:59 +0200 |
commit | 390e8ad3e96d1ab4494976d7ba6f0d0c728090ee (patch) | |
tree | d9dde57013509fb96a5994495bfa81f9fea74a37 /vcl | |
parent | b34fceb3caea3de53abfc1fc2cb4a5a15af5fd6f (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.cxx | 105 | ||||
-rw-r--r-- | vcl/source/bitmap/floyd.hxx | 58 |
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: */ |