[Libreoffice-commits] core.git: vcl/source

Mike Kaganski (via logerrit) logerrit at kemper.freedesktop.org
Tue Jun 30 03:02:17 UTC 2020


 vcl/source/bitmap/BitmapScaleSuperFilter.cxx |  263 ++++++---------------------
 1 file changed, 64 insertions(+), 199 deletions(-)

New commits:
commit 0cc0667caaaeeaa009c06e77431a022bcb58c464
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Mon Jun 29 19:09:08 2020 +0300
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Tue Jun 30 05:01:18 2020 +0200

    Reduce code duplication
    
    Change-Id: Ia5526e61c8dd632fbc5eae2d5c02b46b928f4fa0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97430
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/vcl/source/bitmap/BitmapScaleSuperFilter.cxx b/vcl/source/bitmap/BitmapScaleSuperFilter.cxx
index 78249ce1eec6..4b6d8ede851b 100644
--- a/vcl/source/bitmap/BitmapScaleSuperFilter.cxx
+++ b/vcl/source/bitmap/BitmapScaleSuperFilter.cxx
@@ -32,7 +32,7 @@
 
 namespace {
 
-#define MAP_PRECISION 7
+constexpr int MAP_PRECISION = 7;
 
 typedef sal_Int32 BilinearWeightType;
 
@@ -98,215 +98,78 @@ struct ScaleContext
 
 constexpr long constScaleThreadStrip = 32;
 
-typedef void (*ScaleRangeFn)(ScaleContext & rContext, long nStartY, long nEndY);
+typedef void (*ScaleRangeFn)(const ScaleContext & rContext, long nStartY, long nEndY);
 
-struct ScaleDown24bit
+template <size_t nSize> struct ScaleFunc
 {
-    static int getColorComponent() { return 3; }
+    // for scale down
 
-    static std::vector<int> sumRowsVector()
+    static inline void generateSumRows(Scanline& pTmpX, std::array<int, nSize>& sumRows)
     {
-      std::vector<int> sumRows(3);
-      return sumRows;
+        for (int& n : sumRows)
+            n += (*pTmpX++) << MAP_PRECISION;
     }
 
-    static std::vector<int> sumNumbersVector()
+    static inline void generateSumRows(BilinearWeightType const nWeightX, Scanline& pTmpX,
+                                       std::array<int, nSize>& sumRows)
     {
-      std::vector<int> sumNumbers(3);
-      return sumNumbers;
+        for (int& n : sumRows)
+            n += (nWeightX * (*pTmpX++));
     }
 
-    static inline void generateSumRows(Scanline& pTmpX, std::vector<int>& sumRows)
+    static inline void generateSumRows(BilinearWeightType const nTotalWeightX,
+                                       std::array<int, nSize>& sumRows)
     {
-       sumRows[0] += (*pTmpX) << MAP_PRECISION; pTmpX++;
-       sumRows[1] += (*pTmpX) << MAP_PRECISION; pTmpX++;
-       sumRows[2] += (*pTmpX) << MAP_PRECISION; pTmpX++;
-    }
-
-    static inline void generateSumRows(BilinearWeightType const nWeightX, Scanline& pTmpX, std::vector<int>& sumRows)
-    {
-       sumRows[0] += (nWeightX * (*pTmpX)); pTmpX++;
-       sumRows[1] += (nWeightX * (*pTmpX)); pTmpX++;
-       sumRows[2] += (nWeightX * (*pTmpX)); pTmpX++;
-    }
-
-    static inline void generateSumRows(BilinearWeightType const nTotalWeightX, std::vector<int>& sumRows)
-    {
-       sumRows[0] /= nTotalWeightX;
-       sumRows[1] /= nTotalWeightX;
-       sumRows[2] /= nTotalWeightX;
-    }
-
-    static inline void generateSumNumbers(BilinearWeightType const nWeightY, std::vector<int>& sumRows,
-                                         std::vector<int>& sumNumbers)
-    {
-       sumNumbers[0] += nWeightY * sumRows[0];
-       sumNumbers[1] += nWeightY * sumRows[1];
-       sumNumbers[2] += nWeightY * sumRows[2];
-    }
-
-    static inline void generateSumNumbers(BilinearWeightType const nTotalWeightY, std::vector<int>& sumNumbers) {
-       sumNumbers[0] /= nTotalWeightY;
-       sumNumbers[1] /= nTotalWeightY;
-       sumNumbers[2] /= nTotalWeightY;
-    }
-
-   static inline void calculateDestination(Scanline& pScanDest, std::vector<int>& sumNumbers) {
-
-      *pScanDest = sumNumbers[0]; pScanDest++;
-      *pScanDest = sumNumbers[1]; pScanDest++;
-      *pScanDest = sumNumbers[2]; pScanDest++;
-    }
-
-};
-
-struct ScaleDown32bit
-{
-    static int getColorComponent() { return 4; }
-
-    static std::vector<int> sumRowsVector()
-    {
-      std::vector<int> sumRows(4);
-      return sumRows;
-    }
-
-    static std::vector<int> sumNumbersVector()
-    {
-      std::vector<int> sumNumbers(4);
-      return sumNumbers;
-    }
-
-    static inline void generateSumRows(Scanline& pTmpX, std::vector<int>& sumRows) {
-       sumRows[0] += (*pTmpX) << MAP_PRECISION; pTmpX++;
-       sumRows[1] += (*pTmpX) << MAP_PRECISION; pTmpX++;
-       sumRows[2] += (*pTmpX) << MAP_PRECISION; pTmpX++;
-       sumRows[3] += (*pTmpX) << MAP_PRECISION; pTmpX++;
-    }
-
-    static inline void generateSumRows(BilinearWeightType const nWeightX, Scanline& pTmpX, std::vector<int>& sumRows) {
-       sumRows[0] += (nWeightX * (*pTmpX)); pTmpX++;
-       sumRows[1] += (nWeightX * (*pTmpX)); pTmpX++;
-       sumRows[2] += (nWeightX * (*pTmpX)); pTmpX++;
-       sumRows[3] += (nWeightX * (*pTmpX)); pTmpX++;
-    }
-
-    static inline void generateSumRows(BilinearWeightType const nTotalWeightX, std::vector<int>& sumRows) {
-       sumRows[0] /= nTotalWeightX;
-       sumRows[1] /= nTotalWeightX;
-       sumRows[2] /= nTotalWeightX;
-       sumRows[3] /= nTotalWeightX;
+        for (int& n : sumRows)
+            n /= nTotalWeightX;
     }
 
     static inline void generateSumNumbers(BilinearWeightType const nWeightY,
-                                std::vector<int>& sumRows, std::vector<int>& sumNumbers)
-    {
-       sumNumbers[0] += nWeightY * sumRows[0];
-       sumNumbers[1] += nWeightY * sumRows[1];
-       sumNumbers[2] += nWeightY * sumRows[2];
-       sumNumbers[3] += nWeightY * sumRows[3];
-    }
-
-    static inline void generateSumNumbers(BilinearWeightType const nTotalWeightY, std::vector<int>& sumNumbers) {
-       sumNumbers[0] /= nTotalWeightY;
-       sumNumbers[1] /= nTotalWeightY;
-       sumNumbers[2] /= nTotalWeightY;
-       sumNumbers[3] /= nTotalWeightY;
-    }
-
-    static inline void calculateDestination(Scanline& pScanDest, std::vector<int>& sumNumbers) {
-      *pScanDest = sumNumbers[0]; pScanDest++;
-      *pScanDest = sumNumbers[1]; pScanDest++;
-      *pScanDest = sumNumbers[2]; pScanDest++;
-      *pScanDest = sumNumbers[3]; pScanDest++;
-    }
-
-};
-
-struct ScaleUp24bit
-{
-    static int getColorComponent() { return 3; }
-    static std::vector<sal_uInt8> colorComponents1()
+                                          std::array<int, nSize>& sumRows,
+                                          std::array<int, nSize>& sumNumbers)
     {
-        std::vector<sal_uInt8> nComponent(3);
-        return nComponent;
+        std::transform(sumRows.begin(), sumRows.end(), sumNumbers.begin(), sumNumbers.begin(),
+                       [nWeightY](int n1, int n2) { return nWeightY * n1 + n2; });
     }
 
-    static std::vector<sal_uInt8> colorComponents2()
+    static inline void generateSumNumbers(BilinearWeightType const nTotalWeightY,
+                                          std::array<int, nSize>& sumNumbers)
     {
-        std::vector<sal_uInt8> nComponent(3);
-        return nComponent;
+        for (int& n : sumNumbers)
+            n /= nTotalWeightY;
     }
 
-    static inline void generateComponent(Scanline & pColorPtr0, Scanline & pColorPtr1,
-                                         BilinearWeightType const nTempFX, std::vector<sal_uInt8>& nComponents)
+    static inline void calculateDestination(Scanline& pScanDest, std::array<int, nSize>& sumNumbers)
     {
-        nComponents[0] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
-        pColorPtr0++; pColorPtr1++;
-        nComponents[1] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
-        pColorPtr0++; pColorPtr1++;
-        nComponents[2] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
+        pScanDest = std::copy(sumNumbers.begin(), sumNumbers.end(), pScanDest);
     }
 
-    static inline void calculteScanDestination(Scanline& pScanDest, BilinearWeightType const nTempFY,
-                                      std::vector<sal_uInt8>& nComponents1, std::vector<sal_uInt8>& nComponents2)
-    {
-        *pScanDest = MAP(nComponents1[0], nComponents2[0], nTempFY);
-        pScanDest++;
-        *pScanDest = MAP(nComponents1[1], nComponents2[1], nTempFY);
-        pScanDest++;
-        *pScanDest = MAP(nComponents1[2], nComponents2[2], nTempFY);
-        pScanDest++;
-    }
-
-};
+    // for scale up
 
-struct ScaleUp32bit
-{
-    static int getColorComponent() { return 4; }
-
-    static std::vector<sal_uInt8> colorComponents1()
+    static inline void generateComponent(Scanline pColorPtr0, Scanline pColorPtr1,
+                                         BilinearWeightType const nTempFX,
+                                         std::array<sal_uInt8, nSize>& nComponents)
     {
-        std::vector<sal_uInt8> nComponent(4);
-        return nComponent;
+        for (sal_uInt8& rComponent : nComponents)
+            rComponent = MAP(*pColorPtr0++, *pColorPtr1++, nTempFX);
     }
 
-    static std::vector<sal_uInt8> colorComponents2()
+    static inline void calculateDestination(Scanline& pScanDest, BilinearWeightType const nTempFY,
+                                            const std::array<sal_uInt8, nSize>& nComponents1,
+                                            const std::array<sal_uInt8, nSize>& nComponents2)
     {
-        std::vector<sal_uInt8> nComponent(4);
-        return nComponent;
+        pScanDest = std::transform(
+            nComponents1.begin(), nComponents1.end(), nComponents2.begin(), pScanDest,
+            [nTempFY](sal_uInt8 c1, sal_uInt8 c2) { return MAP(c1, c2, nTempFY); });
     }
-
-    static inline void generateComponent(Scanline & pColorPtr0, Scanline & pColorPtr1,
-                                         BilinearWeightType const nTempFX, std::vector<sal_uInt8>& nComponents)
-    {
-        nComponents[0] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
-        pColorPtr0++; pColorPtr1++;
-        nComponents[1] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
-        pColorPtr0++; pColorPtr1++;
-        nComponents[2] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
-        pColorPtr0++; pColorPtr1++;
-        nComponents[3] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
-    }
-
-    static inline void calculteScanDestination(Scanline& pScanDest, BilinearWeightType const  nTempFY,
-                                      std::vector<sal_uInt8>& nComponents1, std::vector<sal_uInt8>& nComponents2)
-    {
-        *pScanDest = MAP(nComponents1[0], nComponents2[0], nTempFY);
-        pScanDest++;
-        *pScanDest = MAP(nComponents1[1], nComponents2[1], nTempFY);
-        pScanDest++;
-        *pScanDest = MAP(nComponents1[2], nComponents2[2], nTempFY);
-        pScanDest++;
-        *pScanDest = MAP(nComponents1[3], nComponents2[3], nTempFY);
-        pScanDest++;
-    }
-
 };
 
-template<typename ScaleFunction>
-void scaleDown (ScaleContext &rCtx, long nStartY, long nEndY)
+template <int nColorBits>
+void scaleDown (const ScaleContext &rCtx, long nStartY, long nEndY)
 {
-    const int constColorComponents = ScaleFunction::getColorComponent();
+    constexpr int nColorComponents = nColorBits / 8;
+    static_assert(nColorComponents * 8 == nColorBits, "nColorBits must be divisible by 8");
+    using ScaleFunction = ScaleFunc<nColorComponents>;
     const long nStartX = 0;
     const long nEndX = rCtx.mnDestW - 1;
 
@@ -349,15 +212,15 @@ void scaleDown (ScaleContext &rCtx, long nStartY, long nEndY)
                                 1 : (rCtx.maMapIX[nRight] - rCtx.maMapIX[nLeft]);
             }
 
-            std::vector<int> sumNumbers = ScaleFunction::sumNumbersVector();
+            std::array<int, nColorComponents> sumNumbers{}; // zero-initialize
             BilinearWeightType nTotalWeightY = 0;
 
             for (long i = 0; i<= nLineRange; i++)
             {
                 Scanline pTmpY = rCtx.mpSrc->GetScanline(nLineStart + i);
-                Scanline pTmpX = pTmpY + constColorComponents * nRowStart;
+                Scanline pTmpX = pTmpY + nColorComponents * nRowStart;
 
-                std::vector<int> sumRows = ScaleFunction::sumRowsVector();
+                std::array<int, nColorComponents> sumRows{}; // zero-initialize
                 BilinearWeightType nTotalWeightX = 0;
 
                 for (long j = 0; j <= nRowRange; j++)
@@ -416,10 +279,12 @@ void scaleDown (ScaleContext &rCtx, long nStartY, long nEndY)
     }
 }
 
-template <typename ScaleFunction>
-void scaleUp(ScaleContext &rCtx, long nStartY, long nEndY)
+template <int nColorBits>
+void scaleUp(const ScaleContext &rCtx, long nStartY, long nEndY)
 {
-    const int nColorComponents = ScaleFunction::getColorComponent();
+    constexpr int nColorComponents = nColorBits / 8;
+    static_assert(nColorComponents * 8 == nColorBits, "nColorBits must be divisible by 8");
+    using ScaleFunction = ScaleFunc<nColorComponents>;
     const long nStartX = 0;
     const long nEndX = rCtx.mnDestW - 1;
 
@@ -432,8 +297,8 @@ void scaleUp(ScaleContext &rCtx, long nStartY, long nEndY)
         Scanline pLine1 = rCtx.mpSrc->GetScanline(nTempY+1);
         Scanline pScanDest = rCtx.mpDest->GetScanline(nY);
 
-        std::vector<sal_uInt8> nComponents1 = ScaleFunction::colorComponents1();
-        std::vector<sal_uInt8> nComponents2 = ScaleFunction::colorComponents2();
+        std::array<sal_uInt8, nColorComponents> nComponents1; // no need to initialize since it's
+        std::array<sal_uInt8, nColorComponents> nComponents2; // initialized in generateComponent
 
         Scanline pColorPtr0;
         Scanline pColorPtr1;
@@ -452,7 +317,7 @@ void scaleUp(ScaleContext &rCtx, long nStartY, long nEndY)
             pColorPtr1 = pColorPtr0 + nColorComponents;
 
             ScaleFunction::generateComponent(pColorPtr0, pColorPtr1, nTempFX, nComponents2);
-            ScaleFunction::calculteScanDestination(pScanDest, nTempFY, nComponents1, nComponents2);
+            ScaleFunction::calculateDestination(pScanDest, nTempFY, nComponents1, nComponents2);
          }
     }
 }
@@ -460,14 +325,14 @@ void scaleUp(ScaleContext &rCtx, long nStartY, long nEndY)
 class ScaleTask : public comphelper::ThreadTask
 {
     ScaleRangeFn mpScaleRangeFunction;
-    ScaleContext& mrContext;
+    const ScaleContext& mrContext;
     long mnStartY;
     long mnEndY;
 
 public:
     explicit ScaleTask(const std::shared_ptr<comphelper::ThreadTaskTag>& pTag,
                        ScaleRangeFn pScaleRangeFunction,
-                       ScaleContext& rContext,
+                       const ScaleContext& rContext,
                        long nStartY, long nEndY)
         : comphelper::ThreadTask(pTag)
         , mpScaleRangeFunction(pScaleRangeFunction)
@@ -482,7 +347,7 @@ public:
     }
 };
 
-void scaleUpPalette8bit(ScaleContext &rCtx, long nStartY, long nEndY)
+void scaleUpPalette8bit(const ScaleContext &rCtx, long nStartY, long nEndY)
 {
     const long nStartX = 0, nEndX = rCtx.mnDestW - 1;
 
@@ -520,7 +385,7 @@ void scaleUpPalette8bit(ScaleContext &rCtx, long nStartY, long nEndY)
     }
 }
 
-void scaleUpPaletteGeneral(ScaleContext &rCtx, long nStartY, long nEndY)
+void scaleUpPaletteGeneral(const ScaleContext &rCtx, long nStartY, long nEndY)
 {
     const long nStartX = 0, nEndX = rCtx.mnDestW - 1;
 
@@ -555,7 +420,7 @@ void scaleUpPaletteGeneral(ScaleContext &rCtx, long nStartY, long nEndY)
     }
 }
 
-void scaleUpNonPaletteGeneral(ScaleContext &rCtx, long nStartY, long nEndY)
+void scaleUpNonPaletteGeneral(const ScaleContext &rCtx, long nStartY, long nEndY)
 {
     const long nStartX = 0, nEndX = rCtx.mnDestW - 1;
 
@@ -590,7 +455,7 @@ void scaleUpNonPaletteGeneral(ScaleContext &rCtx, long nStartY, long nEndY)
     }
 }
 
-void scaleDownPalette8bit(ScaleContext &rCtx, long nStartY, long nEndY)
+void scaleDownPalette8bit(const ScaleContext &rCtx, long nStartY, long nEndY)
 {
     const long nStartX = 0, nEndX = rCtx.mnDestW - 1;
 
@@ -715,7 +580,7 @@ void scaleDownPalette8bit(ScaleContext &rCtx, long nStartY, long nEndY)
     }
 }
 
-void scaleDownPaletteGeneral(ScaleContext &rCtx, long nStartY, long nEndY)
+void scaleDownPaletteGeneral(const ScaleContext &rCtx, long nStartY, long nEndY)
 {
     const long nStartX = 0, nEndX = rCtx.mnDestW - 1;
 
@@ -843,7 +708,7 @@ void scaleDownPaletteGeneral(ScaleContext &rCtx, long nStartY, long nEndY)
     }
 }
 
-void scaleDownNonPaletteGeneral(ScaleContext &rCtx, long nStartY, long nEndY)
+void scaleDownNonPaletteGeneral(const ScaleContext &rCtx, long nStartY, long nEndY)
 {
     const long nStartX = 0, nEndX = rCtx.mnDestW - 1;
 
@@ -1039,7 +904,7 @@ BitmapEx BitmapScaleSuperFilter::execute(BitmapEx const& rBitmap) const
         if (pReadAccess && pWriteAccess)
         {
             ScaleRangeFn pScaleRangeFn;
-            ScaleContext aContext( pReadAccess.get(),
+            const ScaleContext aContext( pReadAccess.get(),
                                    pWriteAccess.get(),
                                    pReadAccess->Width(),
                                    pWriteAccess->Width(),
@@ -1082,13 +947,13 @@ BitmapEx BitmapScaleSuperFilter::execute(BitmapEx const& rBitmap) const
                 {
                 case ScanlineFormat::N24BitTcBgr:
                 case ScanlineFormat::N24BitTcRgb:
-                    pScaleRangeFn = bScaleUp ? scaleUp<ScaleUp24bit> : scaleDown<ScaleDown24bit>;
+                    pScaleRangeFn = bScaleUp ? scaleUp<24> : scaleDown<24>;
                     break;
                 case ScanlineFormat::N32BitTcRgba:
                 case ScanlineFormat::N32BitTcBgra:
                 case ScanlineFormat::N32BitTcArgb:
                 case ScanlineFormat::N32BitTcAbgr:
-                    pScaleRangeFn = bScaleUp ? scaleUp<ScaleUp32bit> : scaleDown<ScaleDown32bit>;
+                    pScaleRangeFn = bScaleUp ? scaleUp<32> : scaleDown<32>;
                     break;
                 default:
                     pScaleRangeFn = bScaleUp ? scaleUpNonPaletteGeneral


More information about the Libreoffice-commits mailing list