summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
Diffstat (limited to 'vcl')
-rw-r--r--vcl/source/bitmap/BitmapScaleSuperFilter.cxx263
1 files changed, 64 insertions, 199 deletions
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