tdf#39593 reduce copy/paste in BitmapScaleSuperFilter
Change-Id: I1f6387d3ff931b0c885e0cb8ee5b99c880a1484e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94137
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
diff --git a/vcl/source/bitmap/BitmapScaleSuperFilter.cxx b/vcl/source/bitmap/BitmapScaleSuperFilter.cxx
index ff808dd..78249ce 100644
--- a/vcl/source/bitmap/BitmapScaleSuperFilter.cxx
+++ b/vcl/source/bitmap/BitmapScaleSuperFilter.cxx
@@ -98,7 +98,364 @@
constexpr long constScaleThreadStrip = 32;
typedef void (*ScaleRangeFn)(ScaleContext &rContext, long nStartY, long nEndY);
typedef void (*ScaleRangeFn)(ScaleContext & rContext, long nStartY, long nEndY);
struct ScaleDown24bit
{
static int getColorComponent() { return 3; }
static std::vector<int> sumRowsVector()
{
std::vector<int> sumRows(3);
return sumRows;
}
static std::vector<int> sumNumbersVector()
{
std::vector<int> sumNumbers(3);
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++;
}
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;
}
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::vector<sal_uInt8> nComponent(3);
return nComponent;
}
static std::vector<sal_uInt8> colorComponents2()
{
std::vector<sal_uInt8> nComponent(3);
return nComponent;
}
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);
}
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++;
}
};
struct ScaleUp32bit
{
static int getColorComponent() { return 4; }
static std::vector<sal_uInt8> colorComponents1()
{
std::vector<sal_uInt8> nComponent(4);
return nComponent;
}
static std::vector<sal_uInt8> colorComponents2()
{
std::vector<sal_uInt8> nComponent(4);
return nComponent;
}
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)
{
const int constColorComponents = ScaleFunction::getColorComponent();
const long nStartX = 0;
const long nEndX = rCtx.mnDestW - 1;
for (long nY = nStartY; nY <= nEndY; nY++)
{
long nTop = rCtx.mbVMirr ? (nY + 1) : nY;
long nBottom = rCtx.mbVMirr ? nY : (nY + 1);
long nLineStart;
long nLineRange;
if (nY == nEndY)
{
nLineStart = rCtx.maMapIY[nY];
nLineRange = 0;
}
else
{
nLineStart = rCtx.maMapIY[nTop];
nLineRange = (rCtx.maMapIY[nBottom] == rCtx.maMapIY[nTop]) ?
1 : (rCtx.maMapIY[nBottom] - rCtx.maMapIY[nTop]);
}
Scanline pScanDest = rCtx.mpDest->GetScanline(nY);
for (long nX = nStartX; nX <= nEndX; nX++)
{
long nLeft = rCtx.mbHMirr ? (nX + 1) : nX;
long nRight = rCtx.mbHMirr ? nX : (nX + 1);
long nRowStart;
long nRowRange;
if (nX == nEndX)
{
nRowStart = rCtx.maMapIX[nX];
nRowRange = 0;
}
else
{
nRowStart = rCtx.maMapIX[nLeft];
nRowRange = (rCtx.maMapIX[nRight] == rCtx.maMapIX[nLeft]) ?
1 : (rCtx.maMapIX[nRight] - rCtx.maMapIX[nLeft]);
}
std::vector<int> sumNumbers = ScaleFunction::sumNumbersVector();
BilinearWeightType nTotalWeightY = 0;
for (long i = 0; i<= nLineRange; i++)
{
Scanline pTmpY = rCtx.mpSrc->GetScanline(nLineStart + i);
Scanline pTmpX = pTmpY + constColorComponents * nRowStart;
std::vector<int> sumRows = ScaleFunction::sumRowsVector();
BilinearWeightType nTotalWeightX = 0;
for (long j = 0; j <= nRowRange; j++)
{
if (nX == nEndX)
{
ScaleFunction::generateSumRows(pTmpX, sumRows);
nTotalWeightX += lclMaxWeight();
}
else if(j == 0)
{
BilinearWeightType nWeightX = lclMaxWeight() - rCtx.maMapFX[nLeft];
ScaleFunction::generateSumRows(nWeightX, pTmpX, sumRows);
nTotalWeightX += nWeightX;
}
else if ( nRowRange == j )
{
BilinearWeightType nWeightX = rCtx.maMapFX[ nRight ] ;
ScaleFunction::generateSumRows(nWeightX, pTmpX, sumRows);
nTotalWeightX += nWeightX;
}
else
{
ScaleFunction::generateSumRows(pTmpX, sumRows);
nTotalWeightX += lclMaxWeight();
}
}
BilinearWeightType nWeightY = lclMaxWeight();
if (nY == nEndY)
nWeightY = lclMaxWeight();
else if (i == 0)
nWeightY = lclMaxWeight() - rCtx.maMapFY[nTop];
else if (nLineRange == 1)
nWeightY = rCtx.maMapFY[nTop];
else if (nLineRange == i)
nWeightY = rCtx.maMapFY[nBottom];
if (nTotalWeightX)
{
ScaleFunction::generateSumRows(nTotalWeightX, sumRows);
}
ScaleFunction::generateSumNumbers(nWeightY, sumRows, sumNumbers);
nTotalWeightY += nWeightY;
}
if (nTotalWeightY)
{
ScaleFunction::generateSumNumbers(nTotalWeightY, sumNumbers);
}
// Write the calculated color components to the destination
ScaleFunction::calculateDestination(pScanDest, sumNumbers);
}
}
}
template <typename ScaleFunction>
void scaleUp(ScaleContext &rCtx, long nStartY, long nEndY)
{
const int nColorComponents = ScaleFunction::getColorComponent();
const long nStartX = 0;
const long nEndX = rCtx.mnDestW - 1;
for (long nY = nStartY; nY <= nEndY; nY++)
{
long nTempY = rCtx.maMapIY[nY];
BilinearWeightType nTempFY = rCtx.maMapFY[nY];
Scanline pLine0 = rCtx.mpSrc->GetScanline(nTempY+0);
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();
Scanline pColorPtr0;
Scanline pColorPtr1;
for (long nX = nStartX; nX <= nEndX; nX++)
{
long nTempX = rCtx.maMapIX[nX];
BilinearWeightType nTempFX = rCtx.maMapFX[nX];
pColorPtr0 = pLine0 + nTempX * nColorComponents;
pColorPtr1 = pColorPtr0 + nColorComponents;
ScaleFunction::generateComponent(pColorPtr0, pColorPtr1, nTempFX, nComponents1);
pColorPtr0 = pLine1 + nTempX * nColorComponents;
pColorPtr1 = pColorPtr0 + nColorComponents;
ScaleFunction::generateComponent(pColorPtr0, pColorPtr1, nTempFX, nComponents2);
ScaleFunction::calculteScanDestination(pScanDest, nTempFY, nComponents1, nComponents2);
}
}
}
class ScaleTask : public comphelper::ThreadTask
{
@@ -125,67 +482,6 @@
}
};
void scaleUp32bit(ScaleContext &rCtx, long nStartY, long nEndY)
{
const int nColorComponents = 4;
const long nStartX = 0;
const long nEndX = rCtx.mnDestW - 1;
for (long nY = nStartY; nY <= nEndY; nY++)
{
long nTempY = rCtx.maMapIY[nY];
BilinearWeightType nTempFY = rCtx.maMapFY[nY];
Scanline pLine0 = rCtx.mpSrc->GetScanline(nTempY+0);
Scanline pLine1 = rCtx.mpSrc->GetScanline(nTempY+1);
Scanline pScanDest = rCtx.mpDest->GetScanline(nY);
sal_uInt8 nComponent1[nColorComponents];
sal_uInt8 nComponent2[nColorComponents];
Scanline pColorPtr0;
Scanline pColorPtr1;
for (long nX = nStartX; nX <= nEndX; nX++)
{
long nTempX = rCtx.maMapIX[nX];
BilinearWeightType nTempFX = rCtx.maMapFX[nX];
pColorPtr0 = pLine0 + nTempX * nColorComponents;
pColorPtr1 = pColorPtr0 + nColorComponents;
nComponent1[0] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
pColorPtr0++; pColorPtr1++;
nComponent1[1] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
pColorPtr0++; pColorPtr1++;
nComponent1[2] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
pColorPtr0++; pColorPtr1++;
nComponent1[3] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
pColorPtr0 = pLine1 + nTempX * nColorComponents;
pColorPtr1 = pColorPtr0 + nColorComponents;
nComponent2[0] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
pColorPtr0++; pColorPtr1++;
nComponent2[1] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
pColorPtr0++; pColorPtr1++;
nComponent2[2] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
pColorPtr0++; pColorPtr1++;
nComponent2[3] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
*pScanDest = MAP(nComponent1[0], nComponent2[0], nTempFY);
pScanDest++;
*pScanDest = MAP(nComponent1[1], nComponent2[1], nTempFY);
pScanDest++;
*pScanDest = MAP(nComponent1[2], nComponent2[2], nTempFY);
pScanDest++;
*pScanDest = MAP(nComponent1[3], nComponent2[3], nTempFY);
pScanDest++;
}
}
}
void scaleUpPalette8bit(ScaleContext &rCtx, long nStartY, long nEndY)
{
const long nStartX = 0, nEndX = rCtx.mnDestW - 1;
@@ -259,61 +555,6 @@
}
}
void scaleUp24bit(ScaleContext &rCtx, long nStartY, long nEndY)
{
const int nColorComponents = 3;
const long nStartX = 0;
const long nEndX = rCtx.mnDestW - 1;
for (long nY = nStartY; nY <= nEndY; nY++)
{
long nTempY = rCtx.maMapIY[nY];
BilinearWeightType nTempFY = rCtx.maMapFY[nY];
Scanline pLine0 = rCtx.mpSrc->GetScanline(nTempY+0);
Scanline pLine1 = rCtx.mpSrc->GetScanline(nTempY+1);
Scanline pScanDest = rCtx.mpDest->GetScanline(nY);
sal_uInt8 nComponent1[nColorComponents];
sal_uInt8 nComponent2[nColorComponents];
Scanline pColorPtr0;
Scanline pColorPtr1;
for (long nX = nStartX; nX <= nEndX; nX++)
{
long nTempX = rCtx.maMapIX[nX];
BilinearWeightType nTempFX = rCtx.maMapFX[nX];
pColorPtr0 = pLine0 + nTempX * nColorComponents;
pColorPtr1 = pColorPtr0 + nColorComponents;
nComponent1[0] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
pColorPtr0++; pColorPtr1++;
nComponent1[1] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
pColorPtr0++; pColorPtr1++;
nComponent1[2] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
pColorPtr0 = pLine1 + nTempX * nColorComponents;
pColorPtr1 = pColorPtr0 + nColorComponents;
nComponent2[0] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
pColorPtr0++; pColorPtr1++;
nComponent2[1] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
pColorPtr0++; pColorPtr1++;
nComponent2[2] = MAP(*pColorPtr0, *pColorPtr1, nTempFX);
*pScanDest = MAP(nComponent1[0], nComponent2[0], nTempFY);
pScanDest++;
*pScanDest = MAP(nComponent1[1], nComponent2[1], nTempFY);
pScanDest++;
*pScanDest = MAP(nComponent1[2], nComponent2[2], nTempFY);
pScanDest++;
}
}
}
void scaleUpNonPaletteGeneral(ScaleContext &rCtx, long nStartY, long nEndY)
{
const long nStartX = 0, nEndX = rCtx.mnDestW - 1;
@@ -349,148 +590,6 @@
}
}
void scaleDown32bit(ScaleContext &rCtx, long nStartY, long nEndY)
{
const int constColorComponents = 4;
const long nStartX = 0;
const long nEndX = rCtx.mnDestW - 1;
for (long nY = nStartY; nY <= nEndY; nY++)
{
long nTop = rCtx.mbVMirr ? (nY + 1) : nY;
long nBottom = rCtx.mbVMirr ? nY : (nY + 1);
long nLineStart;
long nLineRange;
if (nY == nEndY)
{
nLineStart = rCtx.maMapIY[nY];
nLineRange = 0;
}
else
{
nLineStart = rCtx.maMapIY[nTop];
nLineRange = (rCtx.maMapIY[nBottom] == rCtx.maMapIY[nTop]) ?
1 : (rCtx.maMapIY[nBottom] - rCtx.maMapIY[nTop]);
}
Scanline pScanDest = rCtx.mpDest->GetScanline(nY);
for (long nX = nStartX; nX <= nEndX; nX++)
{
long nLeft = rCtx.mbHMirr ? (nX + 1) : nX;
long nRight = rCtx.mbHMirr ? nX : (nX + 1);
long nRowStart;
long nRowRange;
if (nX == nEndX)
{
nRowStart = rCtx.maMapIX[nX];
nRowRange = 0;
}
else
{
nRowStart = rCtx.maMapIX[nLeft];
nRowRange = (rCtx.maMapIX[nRight] == rCtx.maMapIX[nLeft]) ?
1 : (rCtx.maMapIX[nRight] - rCtx.maMapIX[nLeft]);
}
int nSum1 = 0;
int nSum2 = 0;
int nSum3 = 0;
int nSum4 = 0;
BilinearWeightType nTotalWeightY = 0;
for (long i = 0; i<= nLineRange; i++)
{
Scanline pTmpY = rCtx.mpSrc->GetScanline(nLineStart + i);
Scanline pTmpX = pTmpY + constColorComponents * nRowStart;
int nSumRow1 = 0;
int nSumRow2 = 0;
int nSumRow3 = 0;
int nSumRow4 = 0;
BilinearWeightType nTotalWeightX = 0;
for (long j = 0; j <= nRowRange; j++)
{
if (nX == nEndX)
{
nSumRow1 += (*pTmpX) << MAP_PRECISION; pTmpX++;
nSumRow2 += (*pTmpX) << MAP_PRECISION; pTmpX++;
nSumRow3 += (*pTmpX) << MAP_PRECISION; pTmpX++;
nSumRow4 += (*pTmpX) << MAP_PRECISION; pTmpX++;
nTotalWeightX += lclMaxWeight();
}
else if(j == 0)
{
BilinearWeightType nWeightX = lclMaxWeight() - rCtx.maMapFX[nLeft];
nSumRow1 += (nWeightX * (*pTmpX)); pTmpX++;
nSumRow2 += (nWeightX * (*pTmpX)); pTmpX++;
nSumRow3 += (nWeightX * (*pTmpX)); pTmpX++;
nSumRow4 += (nWeightX * (*pTmpX)); pTmpX++;
nTotalWeightX += nWeightX;
}
else if ( nRowRange == j )
{
BilinearWeightType nWeightX = rCtx.maMapFX[ nRight ] ;
nSumRow1 += (nWeightX * (*pTmpX)); pTmpX++;
nSumRow2 += (nWeightX * (*pTmpX)); pTmpX++;
nSumRow3 += (nWeightX * (*pTmpX)); pTmpX++;
nSumRow4 += (nWeightX * (*pTmpX)); pTmpX++;
nTotalWeightX += nWeightX;
}
else
{
nSumRow1 += (*pTmpX) << MAP_PRECISION; pTmpX++;
nSumRow2 += (*pTmpX) << MAP_PRECISION; pTmpX++;
nSumRow3 += (*pTmpX) << MAP_PRECISION; pTmpX++;
nSumRow4 += (*pTmpX) << MAP_PRECISION; pTmpX++;
nTotalWeightX += lclMaxWeight();
}
}
BilinearWeightType nWeightY = lclMaxWeight();
if (nY == nEndY)
nWeightY = lclMaxWeight();
else if (i == 0)
nWeightY = lclMaxWeight() - rCtx.maMapFY[nTop];
else if (nLineRange == 1)
nWeightY = rCtx.maMapFY[nTop];
else if (nLineRange == i)
nWeightY = rCtx.maMapFY[nBottom];
if (nTotalWeightX)
{
nSumRow1 /= nTotalWeightX;
nSumRow2 /= nTotalWeightX;
nSumRow3 /= nTotalWeightX;
nSumRow4 /= nTotalWeightX;
}
nSum1 += nWeightY * nSumRow1;
nSum2 += nWeightY * nSumRow2;
nSum3 += nWeightY * nSumRow3;
nSum4 += nWeightY * nSumRow4;
nTotalWeightY += nWeightY;
}
if (nTotalWeightY)
{
nSum1 /= nTotalWeightY;
nSum2 /= nTotalWeightY;
nSum3 /= nTotalWeightY;
nSum4 /= nTotalWeightY;
}
// Write the calculated color components to the destination
*pScanDest = nSum1; pScanDest++;
*pScanDest = nSum2; pScanDest++;
*pScanDest = nSum3; pScanDest++;
*pScanDest = nSum4; pScanDest++;
}
}
}
void scaleDownPalette8bit(ScaleContext &rCtx, long nStartY, long nEndY)
{
const long nStartX = 0, nEndX = rCtx.mnDestW - 1;
@@ -744,138 +843,6 @@
}
}
void scaleDown24bit(ScaleContext &rCtx, long nStartY, long nEndY)
{
const int constColorComponents = 3;
const long nStartX = 0;
const long nEndX = rCtx.mnDestW - 1;
for (long nY = nStartY; nY <= nEndY; nY++)
{
long nTop = rCtx.mbVMirr ? (nY + 1) : nY;
long nBottom = rCtx.mbVMirr ? nY : (nY + 1);
long nLineStart;
long nLineRange;
if (nY == nEndY)
{
nLineStart = rCtx.maMapIY[nY];
nLineRange = 0;
}
else
{
nLineStart = rCtx.maMapIY[nTop];
nLineRange = (rCtx.maMapIY[nBottom] == rCtx.maMapIY[nTop]) ?
1 : (rCtx.maMapIY[nBottom] - rCtx.maMapIY[nTop]);
}
Scanline pScanDest = rCtx.mpDest->GetScanline(nY);
for (long nX = nStartX; nX <= nEndX; nX++)
{
long nLeft = rCtx.mbHMirr ? (nX + 1) : nX;
long nRight = rCtx.mbHMirr ? nX : (nX + 1);
long nRowStart;
long nRowRange;
if (nX == nEndX)
{
nRowStart = rCtx.maMapIX[nX];
nRowRange = 0;
}
else
{
nRowStart = rCtx.maMapIX[nLeft];
nRowRange = (rCtx.maMapIX[nRight] == rCtx.maMapIX[nLeft]) ?
1 : (rCtx.maMapIX[nRight] - rCtx.maMapIX[nLeft]);
}
int nSum1 = 0;
int nSum2 = 0;
int nSum3 = 0;
BilinearWeightType nTotalWeightY = 0;
for (long i = 0; i<= nLineRange; i++)
{
Scanline pTmpY = rCtx.mpSrc->GetScanline(nLineStart + i);
Scanline pTmpX = pTmpY + constColorComponents * nRowStart;
int nSumRow1 = 0;
int nSumRow2 = 0;
int nSumRow3 = 0;
BilinearWeightType nTotalWeightX = 0;
for (long j = 0; j <= nRowRange; j++)
{
if (nX == nEndX)
{
nSumRow1 += (*pTmpX) << MAP_PRECISION; pTmpX++;
nSumRow2 += (*pTmpX) << MAP_PRECISION; pTmpX++;
nSumRow3 += (*pTmpX) << MAP_PRECISION; pTmpX++;
nTotalWeightX += lclMaxWeight();
}
else if(j == 0)
{
BilinearWeightType nWeightX = lclMaxWeight() - rCtx.maMapFX[nLeft];
nSumRow1 += (nWeightX * (*pTmpX)); pTmpX++;
nSumRow2 += (nWeightX * (*pTmpX)); pTmpX++;
nSumRow3 += (nWeightX * (*pTmpX)); pTmpX++;
nTotalWeightX += nWeightX;
}
else if ( nRowRange == j )
{
BilinearWeightType nWeightX = rCtx.maMapFX[ nRight ] ;
nSumRow1 += (nWeightX * (*pTmpX)); pTmpX++;
nSumRow2 += (nWeightX * (*pTmpX)); pTmpX++;
nSumRow3 += (nWeightX * (*pTmpX)); pTmpX++;
nTotalWeightX += nWeightX;
}
else
{
nSumRow1 += (*pTmpX) << MAP_PRECISION; pTmpX++;
nSumRow2 += (*pTmpX) << MAP_PRECISION; pTmpX++;
nSumRow3 += (*pTmpX) << MAP_PRECISION; pTmpX++;
nTotalWeightX += lclMaxWeight();
}
}
BilinearWeightType nWeightY = lclMaxWeight();
if (nY == nEndY)
nWeightY = lclMaxWeight();
else if (i == 0)
nWeightY = lclMaxWeight() - rCtx.maMapFY[nTop];
else if (nLineRange == 1)
nWeightY = rCtx.maMapFY[nTop];
else if (nLineRange == i)
nWeightY = rCtx.maMapFY[nBottom];
if (nTotalWeightX)
{
nSumRow1 /= nTotalWeightX;
nSumRow2 /= nTotalWeightX;
nSumRow3 /= nTotalWeightX;
}
nSum1 += nWeightY * nSumRow1;
nSum2 += nWeightY * nSumRow2;
nSum3 += nWeightY * nSumRow3;
nTotalWeightY += nWeightY;
}
if (nTotalWeightY)
{
nSum1 /= nTotalWeightY;
nSum2 /= nTotalWeightY;
nSum3 /= nTotalWeightY;
}
// Write the calculated color components to the destination
*pScanDest = nSum1; pScanDest++;
*pScanDest = nSum2; pScanDest++;
*pScanDest = nSum3; pScanDest++;
}
}
}
void scaleDownNonPaletteGeneral(ScaleContext &rCtx, long nStartY, long nEndY)
{
const long nStartX = 0, nEndX = rCtx.mnDestW - 1;
@@ -1115,13 +1082,13 @@
{
case ScanlineFormat::N24BitTcBgr:
case ScanlineFormat::N24BitTcRgb:
pScaleRangeFn = bScaleUp ? scaleUp24bit : scaleDown24bit;
pScaleRangeFn = bScaleUp ? scaleUp<ScaleUp24bit> : scaleDown<ScaleDown24bit>;
break;
case ScanlineFormat::N32BitTcRgba:
case ScanlineFormat::N32BitTcBgra:
case ScanlineFormat::N32BitTcArgb:
case ScanlineFormat::N32BitTcAbgr:
pScaleRangeFn = bScaleUp ? scaleUp32bit : scaleDown32bit;
pScaleRangeFn = bScaleUp ? scaleUp<ScaleUp32bit> : scaleDown<ScaleDown32bit>;
break;
default:
pScaleRangeFn = bScaleUp ? scaleUpNonPaletteGeneral