flatten some code in vcl
Change-Id: I29638408d60bfa02609ed58839829ed51d319e98 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145045 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
committed by
Noel Grandin
parent
a8d3b8985a
commit
0461eb7564
@@ -23,202 +23,179 @@ BitmapEx BitmapColorQuantizationFilter::execute(BitmapEx const& aBitmapEx) const
|
||||
{
|
||||
Bitmap aBitmap = aBitmapEx.GetBitmap();
|
||||
|
||||
bool bRet = false;
|
||||
|
||||
if (vcl::numberOfColors(aBitmap.getPixelFormat()) <= sal_Int64(mnNewColorCount))
|
||||
{
|
||||
bRet = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Bitmap::ScopedReadAccess pRAcc(aBitmap);
|
||||
return BitmapEx(aBitmap);
|
||||
|
||||
auto const cappedNewColorCount = std::min(mnNewColorCount, sal_uInt16(256));
|
||||
Bitmap::ScopedReadAccess pRAcc(aBitmap);
|
||||
if (!pRAcc)
|
||||
return BitmapEx();
|
||||
|
||||
if (pRAcc)
|
||||
auto const cappedNewColorCount = std::min(mnNewColorCount, sal_uInt16(256));
|
||||
|
||||
const sal_uInt32 nValidBits = 4;
|
||||
const sal_uInt32 nRightShiftBits = 8 - nValidBits;
|
||||
const sal_uInt32 nLeftShiftBits1 = nValidBits;
|
||||
const sal_uInt32 nLeftShiftBits2 = nValidBits << 1;
|
||||
const sal_uInt32 nColorsPerComponent = 1 << nValidBits;
|
||||
const sal_uInt32 nColorOffset = 256 / nColorsPerComponent;
|
||||
const sal_uInt32 nTotalColors = nColorsPerComponent * nColorsPerComponent * nColorsPerComponent;
|
||||
const sal_Int32 nWidth = pRAcc->Width();
|
||||
const sal_Int32 nHeight = pRAcc->Height();
|
||||
std::unique_ptr<PopularColorCount[]> pCountTable(new PopularColorCount[nTotalColors]);
|
||||
|
||||
memset(pCountTable.get(), 0, nTotalColors * sizeof(PopularColorCount));
|
||||
|
||||
for (sal_Int32 nR = 0, nIndex = 0; nR < 256; nR += nColorOffset)
|
||||
{
|
||||
for (sal_Int32 nG = 0; nG < 256; nG += nColorOffset)
|
||||
{
|
||||
const sal_uInt32 nValidBits = 4;
|
||||
const sal_uInt32 nRightShiftBits = 8 - nValidBits;
|
||||
const sal_uInt32 nLeftShiftBits1 = nValidBits;
|
||||
const sal_uInt32 nLeftShiftBits2 = nValidBits << 1;
|
||||
const sal_uInt32 nColorsPerComponent = 1 << nValidBits;
|
||||
const sal_uInt32 nColorOffset = 256 / nColorsPerComponent;
|
||||
const sal_uInt32 nTotalColors
|
||||
= nColorsPerComponent * nColorsPerComponent * nColorsPerComponent;
|
||||
const sal_Int32 nWidth = pRAcc->Width();
|
||||
const sal_Int32 nHeight = pRAcc->Height();
|
||||
std::unique_ptr<PopularColorCount[]> pCountTable(new PopularColorCount[nTotalColors]);
|
||||
|
||||
memset(pCountTable.get(), 0, nTotalColors * sizeof(PopularColorCount));
|
||||
|
||||
for (sal_Int32 nR = 0, nIndex = 0; nR < 256; nR += nColorOffset)
|
||||
for (sal_Int32 nB = 0; nB < 256; nB += nColorOffset)
|
||||
{
|
||||
for (sal_Int32 nG = 0; nG < 256; nG += nColorOffset)
|
||||
{
|
||||
for (sal_Int32 nB = 0; nB < 256; nB += nColorOffset)
|
||||
{
|
||||
pCountTable[nIndex].mnIndex = nIndex;
|
||||
nIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pRAcc->HasPalette())
|
||||
{
|
||||
for (sal_Int32 nY = 0; nY < nHeight; nY++)
|
||||
{
|
||||
Scanline pScanlineRead = pRAcc->GetScanline(nY);
|
||||
for (sal_Int32 nX = 0; nX < nWidth; nX++)
|
||||
{
|
||||
const BitmapColor& rCol
|
||||
= pRAcc->GetPaletteColor(pRAcc->GetIndexFromData(pScanlineRead, nX));
|
||||
pCountTable[((static_cast<sal_uInt32>(rCol.GetRed()) >> nRightShiftBits)
|
||||
<< nLeftShiftBits2)
|
||||
| ((static_cast<sal_uInt32>(rCol.GetGreen()) >> nRightShiftBits)
|
||||
<< nLeftShiftBits1)
|
||||
| (static_cast<sal_uInt32>(rCol.GetBlue()) >> nRightShiftBits)]
|
||||
.mnCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (sal_Int32 nY = 0; nY < nHeight; nY++)
|
||||
{
|
||||
Scanline pScanlineRead = pRAcc->GetScanline(nY);
|
||||
for (sal_Int32 nX = 0; nX < nWidth; nX++)
|
||||
{
|
||||
const BitmapColor aCol(pRAcc->GetPixelFromData(pScanlineRead, nX));
|
||||
pCountTable[((static_cast<sal_uInt32>(aCol.GetRed()) >> nRightShiftBits)
|
||||
<< nLeftShiftBits2)
|
||||
| ((static_cast<sal_uInt32>(aCol.GetGreen()) >> nRightShiftBits)
|
||||
<< nLeftShiftBits1)
|
||||
| (static_cast<sal_uInt32>(aCol.GetBlue()) >> nRightShiftBits)]
|
||||
.mnCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BitmapPalette aNewPal(cappedNewColorCount);
|
||||
|
||||
std::qsort(pCountTable.get(), nTotalColors, sizeof(PopularColorCount),
|
||||
[](const void* p1, const void* p2) {
|
||||
int nRet;
|
||||
|
||||
if (static_cast<PopularColorCount const*>(p1)->mnCount
|
||||
< static_cast<PopularColorCount const*>(p2)->mnCount)
|
||||
nRet = 1;
|
||||
else if (static_cast<PopularColorCount const*>(p1)->mnCount
|
||||
== static_cast<PopularColorCount const*>(p2)->mnCount)
|
||||
nRet = 0;
|
||||
else
|
||||
nRet = -1;
|
||||
|
||||
return nRet;
|
||||
});
|
||||
|
||||
for (sal_uInt16 n = 0; n < cappedNewColorCount; n++)
|
||||
{
|
||||
const PopularColorCount& rPop = pCountTable[n];
|
||||
aNewPal[n] = BitmapColor(
|
||||
static_cast<sal_uInt8>((rPop.mnIndex >> nLeftShiftBits2) << nRightShiftBits),
|
||||
static_cast<sal_uInt8>(
|
||||
((rPop.mnIndex >> nLeftShiftBits1) & (nColorsPerComponent - 1))
|
||||
<< nRightShiftBits),
|
||||
static_cast<sal_uInt8>((rPop.mnIndex & (nColorsPerComponent - 1))
|
||||
<< nRightShiftBits));
|
||||
}
|
||||
|
||||
Bitmap aNewBmp(aBitmap.GetSizePixel(), vcl::PixelFormat::N8_BPP, &aNewPal);
|
||||
BitmapScopedWriteAccess pWAcc(aNewBmp);
|
||||
|
||||
if (pWAcc)
|
||||
{
|
||||
BitmapColor aDstCol(sal_uInt8(0));
|
||||
std::unique_ptr<sal_uInt8[]> pIndexMap(new sal_uInt8[nTotalColors]);
|
||||
|
||||
for (sal_Int32 nR = 0, nIndex = 0; nR < 256; nR += nColorOffset)
|
||||
{
|
||||
for (sal_Int32 nG = 0; nG < 256; nG += nColorOffset)
|
||||
{
|
||||
for (sal_Int32 nB = 0; nB < 256; nB += nColorOffset)
|
||||
{
|
||||
pIndexMap[nIndex++] = static_cast<sal_uInt8>(aNewPal.GetBestIndex(
|
||||
BitmapColor(static_cast<sal_uInt8>(nR), static_cast<sal_uInt8>(nG),
|
||||
static_cast<sal_uInt8>(nB))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pRAcc->HasPalette())
|
||||
{
|
||||
for (sal_Int32 nY = 0; nY < nHeight; nY++)
|
||||
{
|
||||
Scanline pScanline = pWAcc->GetScanline(nY);
|
||||
Scanline pScanlineRead = pRAcc->GetScanline(nY);
|
||||
for (sal_Int32 nX = 0; nX < nWidth; nX++)
|
||||
{
|
||||
const BitmapColor& rCol = pRAcc->GetPaletteColor(
|
||||
pRAcc->GetIndexFromData(pScanlineRead, nX));
|
||||
aDstCol.SetIndex(pIndexMap[((static_cast<sal_uInt32>(rCol.GetRed())
|
||||
>> nRightShiftBits)
|
||||
<< nLeftShiftBits2)
|
||||
| ((static_cast<sal_uInt32>(rCol.GetGreen())
|
||||
>> nRightShiftBits)
|
||||
<< nLeftShiftBits1)
|
||||
| (static_cast<sal_uInt32>(rCol.GetBlue())
|
||||
>> nRightShiftBits)]);
|
||||
pWAcc->SetPixelOnData(pScanline, nX, aDstCol);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (sal_Int32 nY = 0; nY < nHeight; nY++)
|
||||
{
|
||||
Scanline pScanline = pWAcc->GetScanline(nY);
|
||||
Scanline pScanlineRead = pRAcc->GetScanline(nY);
|
||||
|
||||
for (sal_Int32 nX = 0; nX < nWidth; nX++)
|
||||
{
|
||||
const BitmapColor aCol(pRAcc->GetPixelFromData(pScanlineRead, nX));
|
||||
aDstCol.SetIndex(pIndexMap[((static_cast<sal_uInt32>(aCol.GetRed())
|
||||
>> nRightShiftBits)
|
||||
<< nLeftShiftBits2)
|
||||
| ((static_cast<sal_uInt32>(aCol.GetGreen())
|
||||
>> nRightShiftBits)
|
||||
<< nLeftShiftBits1)
|
||||
| (static_cast<sal_uInt32>(aCol.GetBlue())
|
||||
>> nRightShiftBits)]);
|
||||
pWAcc->SetPixelOnData(pScanline, nX, aDstCol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pWAcc.reset();
|
||||
bRet = true;
|
||||
}
|
||||
|
||||
pCountTable.reset();
|
||||
pRAcc.reset();
|
||||
|
||||
if (bRet)
|
||||
{
|
||||
const MapMode aMap(aBitmap.GetPrefMapMode());
|
||||
const Size aSize(aBitmap.GetPrefSize());
|
||||
|
||||
aBitmap = aNewBmp;
|
||||
|
||||
aBitmap.SetPrefMapMode(aMap);
|
||||
aBitmap.SetPrefSize(aSize);
|
||||
pCountTable[nIndex].mnIndex = nIndex;
|
||||
nIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bRet)
|
||||
return BitmapEx(aBitmap);
|
||||
if (pRAcc->HasPalette())
|
||||
{
|
||||
for (sal_Int32 nY = 0; nY < nHeight; nY++)
|
||||
{
|
||||
Scanline pScanlineRead = pRAcc->GetScanline(nY);
|
||||
for (sal_Int32 nX = 0; nX < nWidth; nX++)
|
||||
{
|
||||
const BitmapColor& rCol
|
||||
= pRAcc->GetPaletteColor(pRAcc->GetIndexFromData(pScanlineRead, nX));
|
||||
pCountTable[((static_cast<sal_uInt32>(rCol.GetRed()) >> nRightShiftBits)
|
||||
<< nLeftShiftBits2)
|
||||
| ((static_cast<sal_uInt32>(rCol.GetGreen()) >> nRightShiftBits)
|
||||
<< nLeftShiftBits1)
|
||||
| (static_cast<sal_uInt32>(rCol.GetBlue()) >> nRightShiftBits)]
|
||||
.mnCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (sal_Int32 nY = 0; nY < nHeight; nY++)
|
||||
{
|
||||
Scanline pScanlineRead = pRAcc->GetScanline(nY);
|
||||
for (sal_Int32 nX = 0; nX < nWidth; nX++)
|
||||
{
|
||||
const BitmapColor aCol(pRAcc->GetPixelFromData(pScanlineRead, nX));
|
||||
pCountTable[((static_cast<sal_uInt32>(aCol.GetRed()) >> nRightShiftBits)
|
||||
<< nLeftShiftBits2)
|
||||
| ((static_cast<sal_uInt32>(aCol.GetGreen()) >> nRightShiftBits)
|
||||
<< nLeftShiftBits1)
|
||||
| (static_cast<sal_uInt32>(aCol.GetBlue()) >> nRightShiftBits)]
|
||||
.mnCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BitmapEx();
|
||||
BitmapPalette aNewPal(cappedNewColorCount);
|
||||
|
||||
std::qsort(pCountTable.get(), nTotalColors, sizeof(PopularColorCount),
|
||||
[](const void* p1, const void* p2) {
|
||||
int nRet;
|
||||
|
||||
if (static_cast<PopularColorCount const*>(p1)->mnCount
|
||||
< static_cast<PopularColorCount const*>(p2)->mnCount)
|
||||
nRet = 1;
|
||||
else if (static_cast<PopularColorCount const*>(p1)->mnCount
|
||||
== static_cast<PopularColorCount const*>(p2)->mnCount)
|
||||
nRet = 0;
|
||||
else
|
||||
nRet = -1;
|
||||
|
||||
return nRet;
|
||||
});
|
||||
|
||||
for (sal_uInt16 n = 0; n < cappedNewColorCount; n++)
|
||||
{
|
||||
const PopularColorCount& rPop = pCountTable[n];
|
||||
aNewPal[n] = BitmapColor(
|
||||
static_cast<sal_uInt8>((rPop.mnIndex >> nLeftShiftBits2) << nRightShiftBits),
|
||||
static_cast<sal_uInt8>(((rPop.mnIndex >> nLeftShiftBits1) & (nColorsPerComponent - 1))
|
||||
<< nRightShiftBits),
|
||||
static_cast<sal_uInt8>((rPop.mnIndex & (nColorsPerComponent - 1)) << nRightShiftBits));
|
||||
}
|
||||
|
||||
Bitmap aNewBmp(aBitmap.GetSizePixel(), vcl::PixelFormat::N8_BPP, &aNewPal);
|
||||
BitmapScopedWriteAccess pWAcc(aNewBmp);
|
||||
if (!pWAcc)
|
||||
return BitmapEx();
|
||||
|
||||
BitmapColor aDstCol(sal_uInt8(0));
|
||||
std::unique_ptr<sal_uInt8[]> pIndexMap(new sal_uInt8[nTotalColors]);
|
||||
|
||||
for (sal_Int32 nR = 0, nIndex = 0; nR < 256; nR += nColorOffset)
|
||||
{
|
||||
for (sal_Int32 nG = 0; nG < 256; nG += nColorOffset)
|
||||
{
|
||||
for (sal_Int32 nB = 0; nB < 256; nB += nColorOffset)
|
||||
{
|
||||
pIndexMap[nIndex++] = static_cast<sal_uInt8>(aNewPal.GetBestIndex(
|
||||
BitmapColor(static_cast<sal_uInt8>(nR), static_cast<sal_uInt8>(nG),
|
||||
static_cast<sal_uInt8>(nB))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pRAcc->HasPalette())
|
||||
{
|
||||
for (sal_Int32 nY = 0; nY < nHeight; nY++)
|
||||
{
|
||||
Scanline pScanline = pWAcc->GetScanline(nY);
|
||||
Scanline pScanlineRead = pRAcc->GetScanline(nY);
|
||||
for (sal_Int32 nX = 0; nX < nWidth; nX++)
|
||||
{
|
||||
const BitmapColor& rCol
|
||||
= pRAcc->GetPaletteColor(pRAcc->GetIndexFromData(pScanlineRead, nX));
|
||||
aDstCol.SetIndex(
|
||||
pIndexMap[((static_cast<sal_uInt32>(rCol.GetRed()) >> nRightShiftBits)
|
||||
<< nLeftShiftBits2)
|
||||
| ((static_cast<sal_uInt32>(rCol.GetGreen()) >> nRightShiftBits)
|
||||
<< nLeftShiftBits1)
|
||||
| (static_cast<sal_uInt32>(rCol.GetBlue()) >> nRightShiftBits)]);
|
||||
pWAcc->SetPixelOnData(pScanline, nX, aDstCol);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (sal_Int32 nY = 0; nY < nHeight; nY++)
|
||||
{
|
||||
Scanline pScanline = pWAcc->GetScanline(nY);
|
||||
Scanline pScanlineRead = pRAcc->GetScanline(nY);
|
||||
|
||||
for (sal_Int32 nX = 0; nX < nWidth; nX++)
|
||||
{
|
||||
const BitmapColor aCol(pRAcc->GetPixelFromData(pScanlineRead, nX));
|
||||
aDstCol.SetIndex(
|
||||
pIndexMap[((static_cast<sal_uInt32>(aCol.GetRed()) >> nRightShiftBits)
|
||||
<< nLeftShiftBits2)
|
||||
| ((static_cast<sal_uInt32>(aCol.GetGreen()) >> nRightShiftBits)
|
||||
<< nLeftShiftBits1)
|
||||
| (static_cast<sal_uInt32>(aCol.GetBlue()) >> nRightShiftBits)]);
|
||||
pWAcc->SetPixelOnData(pScanline, nX, aDstCol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pWAcc.reset();
|
||||
pCountTable.reset();
|
||||
pRAcc.reset();
|
||||
|
||||
const MapMode aMap(aBitmap.GetPrefMapMode());
|
||||
const Size aSize(aBitmap.GetPrefSize());
|
||||
|
||||
aBitmap = aNewBmp;
|
||||
|
||||
aBitmap.SetPrefMapMode(aMap);
|
||||
aBitmap.SetPrefSize(aSize);
|
||||
|
||||
return BitmapEx(aBitmap);
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
||||
@@ -25,179 +25,167 @@ BitmapEx BitmapConvolutionMatrixFilter::execute(BitmapEx const& rBitmapEx) const
|
||||
|
||||
const sal_Int32 nDivisor = 8;
|
||||
Bitmap::ScopedReadAccess pReadAcc(aBitmap);
|
||||
bool bRet = false;
|
||||
if (!pReadAcc)
|
||||
return BitmapEx();
|
||||
|
||||
if (pReadAcc)
|
||||
Bitmap aNewBmp(aBitmap.GetSizePixel(), vcl::PixelFormat::N24_BPP);
|
||||
BitmapScopedWriteAccess pWriteAcc(aNewBmp);
|
||||
if (!pWriteAcc)
|
||||
return BitmapEx();
|
||||
|
||||
const sal_Int32 nWidth = pWriteAcc->Width(), nWidth2 = nWidth + 2;
|
||||
const sal_Int32 nHeight = pWriteAcc->Height(), nHeight2 = nHeight + 2;
|
||||
std::unique_ptr<sal_Int32[]> pColm(new sal_Int32[nWidth2]);
|
||||
std::unique_ptr<sal_Int32[]> pRows(new sal_Int32[nHeight2]);
|
||||
std::unique_ptr<BitmapColor[]> pColRow1(new BitmapColor[nWidth2]);
|
||||
std::unique_ptr<BitmapColor[]> pColRow2(new BitmapColor[nWidth2]);
|
||||
std::unique_ptr<BitmapColor[]> pColRow3(new BitmapColor[nWidth2]);
|
||||
BitmapColor* pRowTmp1 = pColRow1.get();
|
||||
BitmapColor* pRowTmp2 = pColRow2.get();
|
||||
BitmapColor* pRowTmp3 = pColRow3.get();
|
||||
BitmapColor* pColor;
|
||||
sal_Int32 nY, nX, i, nSumR, nSumG, nSumB, nMatrixVal, nTmp;
|
||||
std::array<std::array<sal_Int32, 256>, 9> aKoeff;
|
||||
sal_Int32* pTmp;
|
||||
|
||||
// create LUT of products of matrix value and possible color component values
|
||||
for (nY = 0; nY < 9; nY++)
|
||||
{
|
||||
Bitmap aNewBmp(aBitmap.GetSizePixel(), vcl::PixelFormat::N24_BPP);
|
||||
BitmapScopedWriteAccess pWriteAcc(aNewBmp);
|
||||
|
||||
if (pWriteAcc)
|
||||
for (nX = nTmp = 0, nMatrixVal = mrMatrix[nY]; nX < 256; nX++, nTmp += nMatrixVal)
|
||||
{
|
||||
const sal_Int32 nWidth = pWriteAcc->Width(), nWidth2 = nWidth + 2;
|
||||
const sal_Int32 nHeight = pWriteAcc->Height(), nHeight2 = nHeight + 2;
|
||||
std::unique_ptr<sal_Int32[]> pColm(new sal_Int32[nWidth2]);
|
||||
std::unique_ptr<sal_Int32[]> pRows(new sal_Int32[nHeight2]);
|
||||
std::unique_ptr<BitmapColor[]> pColRow1(new BitmapColor[nWidth2]);
|
||||
std::unique_ptr<BitmapColor[]> pColRow2(new BitmapColor[nWidth2]);
|
||||
std::unique_ptr<BitmapColor[]> pColRow3(new BitmapColor[nWidth2]);
|
||||
BitmapColor* pRowTmp1 = pColRow1.get();
|
||||
BitmapColor* pRowTmp2 = pColRow2.get();
|
||||
BitmapColor* pRowTmp3 = pColRow3.get();
|
||||
BitmapColor* pColor;
|
||||
sal_Int32 nY, nX, i, nSumR, nSumG, nSumB, nMatrixVal, nTmp;
|
||||
std::array<std::array<sal_Int32, 256>, 9> aKoeff;
|
||||
sal_Int32* pTmp;
|
||||
|
||||
// create LUT of products of matrix value and possible color component values
|
||||
for (nY = 0; nY < 9; nY++)
|
||||
{
|
||||
for (nX = nTmp = 0, nMatrixVal = mrMatrix[nY]; nX < 256; nX++, nTmp += nMatrixVal)
|
||||
{
|
||||
aKoeff[nY][nX] = nTmp;
|
||||
}
|
||||
}
|
||||
|
||||
// create column LUT
|
||||
for (i = 0; i < nWidth2; i++)
|
||||
{
|
||||
pColm[i] = (i > 0) ? (i - 1) : 0;
|
||||
}
|
||||
|
||||
pColm[nWidth + 1] = pColm[nWidth];
|
||||
|
||||
// create row LUT
|
||||
for (i = 0; i < nHeight2; i++)
|
||||
{
|
||||
pRows[i] = (i > 0) ? (i - 1) : 0;
|
||||
}
|
||||
|
||||
pRows[nHeight + 1] = pRows[nHeight];
|
||||
|
||||
// read first three rows of bitmap color
|
||||
for (i = 0; i < nWidth2; i++)
|
||||
{
|
||||
pColRow1[i] = pReadAcc->GetColor(pRows[0], pColm[i]);
|
||||
pColRow2[i] = pReadAcc->GetColor(pRows[1], pColm[i]);
|
||||
pColRow3[i] = pReadAcc->GetColor(pRows[2], pColm[i]);
|
||||
}
|
||||
|
||||
// do convolution
|
||||
for (nY = 0; nY < nHeight;)
|
||||
{
|
||||
Scanline pScanline = pWriteAcc->GetScanline(nY);
|
||||
for (nX = 0; nX < nWidth; nX++)
|
||||
{
|
||||
// first row
|
||||
pTmp = aKoeff[0].data();
|
||||
pColor = pRowTmp1 + nX;
|
||||
nSumR = pTmp[pColor->GetRed()];
|
||||
nSumG = pTmp[pColor->GetGreen()];
|
||||
nSumB = pTmp[pColor->GetBlue()];
|
||||
|
||||
pTmp = aKoeff[1].data();
|
||||
nSumR += pTmp[(++pColor)->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
pTmp = aKoeff[2].data();
|
||||
nSumR += pTmp[(++pColor)->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
// second row
|
||||
pTmp = aKoeff[3].data();
|
||||
pColor = pRowTmp2 + nX;
|
||||
nSumR += pTmp[pColor->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
pTmp = aKoeff[4].data();
|
||||
nSumR += pTmp[(++pColor)->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
pTmp = aKoeff[5].data();
|
||||
nSumR += pTmp[(++pColor)->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
// third row
|
||||
pTmp = aKoeff[6].data();
|
||||
pColor = pRowTmp3 + nX;
|
||||
nSumR += pTmp[pColor->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
pTmp = aKoeff[7].data();
|
||||
nSumR += pTmp[(++pColor)->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
pTmp = aKoeff[8].data();
|
||||
nSumR += pTmp[(++pColor)->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
// calculate destination color
|
||||
pWriteAcc->SetPixelOnData(
|
||||
pScanline, nX,
|
||||
BitmapColor(static_cast<sal_uInt8>(MinMax(nSumR / nDivisor, 0, 255)),
|
||||
static_cast<sal_uInt8>(MinMax(nSumG / nDivisor, 0, 255)),
|
||||
static_cast<sal_uInt8>(MinMax(nSumB / nDivisor, 0, 255))));
|
||||
}
|
||||
|
||||
if (++nY < nHeight)
|
||||
{
|
||||
if (pRowTmp1 == pColRow1.get())
|
||||
{
|
||||
pRowTmp1 = pColRow2.get();
|
||||
pRowTmp2 = pColRow3.get();
|
||||
pRowTmp3 = pColRow1.get();
|
||||
}
|
||||
else if (pRowTmp1 == pColRow2.get())
|
||||
{
|
||||
pRowTmp1 = pColRow3.get();
|
||||
pRowTmp2 = pColRow1.get();
|
||||
pRowTmp3 = pColRow2.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
pRowTmp1 = pColRow1.get();
|
||||
pRowTmp2 = pColRow2.get();
|
||||
pRowTmp3 = pColRow3.get();
|
||||
}
|
||||
|
||||
for (i = 0; i < nWidth2; i++)
|
||||
{
|
||||
pRowTmp3[i] = pReadAcc->GetColor(pRows[nY + 2], pColm[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pWriteAcc.reset();
|
||||
|
||||
bRet = true;
|
||||
}
|
||||
|
||||
pReadAcc.reset();
|
||||
|
||||
if (bRet)
|
||||
{
|
||||
const MapMode aMap(aBitmap.GetPrefMapMode());
|
||||
const Size aPrefSize(aBitmap.GetPrefSize());
|
||||
|
||||
aBitmap = aNewBmp;
|
||||
|
||||
aBitmap.SetPrefMapMode(aMap);
|
||||
aBitmap.SetPrefSize(aPrefSize);
|
||||
aKoeff[nY][nX] = nTmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (bRet)
|
||||
return BitmapEx(aBitmap);
|
||||
// create column LUT
|
||||
for (i = 0; i < nWidth2; i++)
|
||||
{
|
||||
pColm[i] = (i > 0) ? (i - 1) : 0;
|
||||
}
|
||||
|
||||
return BitmapEx();
|
||||
pColm[nWidth + 1] = pColm[nWidth];
|
||||
|
||||
// create row LUT
|
||||
for (i = 0; i < nHeight2; i++)
|
||||
{
|
||||
pRows[i] = (i > 0) ? (i - 1) : 0;
|
||||
}
|
||||
|
||||
pRows[nHeight + 1] = pRows[nHeight];
|
||||
|
||||
// read first three rows of bitmap color
|
||||
for (i = 0; i < nWidth2; i++)
|
||||
{
|
||||
pColRow1[i] = pReadAcc->GetColor(pRows[0], pColm[i]);
|
||||
pColRow2[i] = pReadAcc->GetColor(pRows[1], pColm[i]);
|
||||
pColRow3[i] = pReadAcc->GetColor(pRows[2], pColm[i]);
|
||||
}
|
||||
|
||||
// do convolution
|
||||
for (nY = 0; nY < nHeight;)
|
||||
{
|
||||
Scanline pScanline = pWriteAcc->GetScanline(nY);
|
||||
for (nX = 0; nX < nWidth; nX++)
|
||||
{
|
||||
// first row
|
||||
pTmp = aKoeff[0].data();
|
||||
pColor = pRowTmp1 + nX;
|
||||
nSumR = pTmp[pColor->GetRed()];
|
||||
nSumG = pTmp[pColor->GetGreen()];
|
||||
nSumB = pTmp[pColor->GetBlue()];
|
||||
|
||||
pTmp = aKoeff[1].data();
|
||||
nSumR += pTmp[(++pColor)->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
pTmp = aKoeff[2].data();
|
||||
nSumR += pTmp[(++pColor)->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
// second row
|
||||
pTmp = aKoeff[3].data();
|
||||
pColor = pRowTmp2 + nX;
|
||||
nSumR += pTmp[pColor->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
pTmp = aKoeff[4].data();
|
||||
nSumR += pTmp[(++pColor)->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
pTmp = aKoeff[5].data();
|
||||
nSumR += pTmp[(++pColor)->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
// third row
|
||||
pTmp = aKoeff[6].data();
|
||||
pColor = pRowTmp3 + nX;
|
||||
nSumR += pTmp[pColor->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
pTmp = aKoeff[7].data();
|
||||
nSumR += pTmp[(++pColor)->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
pTmp = aKoeff[8].data();
|
||||
nSumR += pTmp[(++pColor)->GetRed()];
|
||||
nSumG += pTmp[pColor->GetGreen()];
|
||||
nSumB += pTmp[pColor->GetBlue()];
|
||||
|
||||
// calculate destination color
|
||||
pWriteAcc->SetPixelOnData(
|
||||
pScanline, nX,
|
||||
BitmapColor(static_cast<sal_uInt8>(MinMax(nSumR / nDivisor, 0, 255)),
|
||||
static_cast<sal_uInt8>(MinMax(nSumG / nDivisor, 0, 255)),
|
||||
static_cast<sal_uInt8>(MinMax(nSumB / nDivisor, 0, 255))));
|
||||
}
|
||||
|
||||
if (++nY < nHeight)
|
||||
{
|
||||
if (pRowTmp1 == pColRow1.get())
|
||||
{
|
||||
pRowTmp1 = pColRow2.get();
|
||||
pRowTmp2 = pColRow3.get();
|
||||
pRowTmp3 = pColRow1.get();
|
||||
}
|
||||
else if (pRowTmp1 == pColRow2.get())
|
||||
{
|
||||
pRowTmp1 = pColRow3.get();
|
||||
pRowTmp2 = pColRow1.get();
|
||||
pRowTmp3 = pColRow2.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
pRowTmp1 = pColRow1.get();
|
||||
pRowTmp2 = pColRow2.get();
|
||||
pRowTmp3 = pColRow3.get();
|
||||
}
|
||||
|
||||
for (i = 0; i < nWidth2; i++)
|
||||
{
|
||||
pRowTmp3[i] = pReadAcc->GetColor(pRows[nY + 2], pColm[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pWriteAcc.reset();
|
||||
pReadAcc.reset();
|
||||
|
||||
const MapMode aMap(aBitmap.GetPrefMapMode());
|
||||
const Size aPrefSize(aBitmap.GetPrefSize());
|
||||
|
||||
aBitmap = aNewBmp;
|
||||
|
||||
aBitmap.SetPrefMapMode(aMap);
|
||||
aBitmap.SetPrefSize(aPrefSize);
|
||||
|
||||
return BitmapEx(aBitmap);
|
||||
}
|
||||
|
||||
const sal_Int32 g_SharpenMatrix[] = { -1, -1, -1, -1, 16, -1, -1, -1, -1 };
|
||||
|
||||
@@ -24,137 +24,120 @@ BitmapEx BitmapEmbossGreyFilter::execute(BitmapEx const& rBitmapEx) const
|
||||
{
|
||||
Bitmap aBitmap(rBitmapEx.GetBitmap());
|
||||
|
||||
bool bRet = aBitmap.ImplMakeGreyscales();
|
||||
if (!aBitmap.ImplMakeGreyscales())
|
||||
return BitmapEx();
|
||||
|
||||
if (bRet)
|
||||
Bitmap::ScopedReadAccess pReadAcc(aBitmap);
|
||||
if (!pReadAcc)
|
||||
return BitmapEx();
|
||||
|
||||
Bitmap aNewBmp(aBitmap.GetSizePixel(), vcl::PixelFormat::N8_BPP, &pReadAcc->GetPalette());
|
||||
BitmapScopedWriteAccess pWriteAcc(aNewBmp);
|
||||
if (!pWriteAcc)
|
||||
return BitmapEx();
|
||||
|
||||
BitmapColor aGrey(sal_uInt8(0));
|
||||
const sal_Int32 nWidth = pWriteAcc->Width();
|
||||
const sal_Int32 nHeight = pWriteAcc->Height();
|
||||
sal_Int32 nGrey11, nGrey12, nGrey13;
|
||||
sal_Int32 nGrey21, nGrey22, nGrey23;
|
||||
sal_Int32 nGrey31, nGrey32, nGrey33;
|
||||
double fAzim = basegfx::deg2rad<100>(mnAzimuthAngle100);
|
||||
double fElev = basegfx::deg2rad<100>(mnElevationAngle100);
|
||||
std::unique_ptr<sal_Int32[]> pHMap(new sal_Int32[nWidth + 2]);
|
||||
std::unique_ptr<sal_Int32[]> pVMap(new sal_Int32[nHeight + 2]);
|
||||
sal_Int32 nX, nY, nNx, nNy, nDotL;
|
||||
const sal_Int32 nLx = FRound(cos(fAzim) * cos(fElev) * 255.0);
|
||||
const sal_Int32 nLy = FRound(sin(fAzim) * cos(fElev) * 255.0);
|
||||
const sal_Int32 nLz = FRound(sin(fElev) * 255.0);
|
||||
const auto nZ2 = ((6 * 255) / 4) * ((6 * 255) / 4);
|
||||
const sal_Int32 nNzLz = ((6 * 255) / 4) * nLz;
|
||||
const sal_uInt8 cLz = static_cast<sal_uInt8>(std::clamp(nLz, sal_Int32(0), sal_Int32(255)));
|
||||
|
||||
// fill mapping tables
|
||||
pHMap[0] = 0;
|
||||
|
||||
for (nX = 1; nX <= nWidth; nX++)
|
||||
{
|
||||
bRet = false;
|
||||
pHMap[nX] = nX - 1;
|
||||
}
|
||||
|
||||
Bitmap::ScopedReadAccess pReadAcc(aBitmap);
|
||||
pHMap[nWidth + 1] = nWidth - 1;
|
||||
|
||||
if (pReadAcc)
|
||||
pVMap[0] = 0;
|
||||
|
||||
for (nY = 1; nY <= nHeight; nY++)
|
||||
{
|
||||
pVMap[nY] = nY - 1;
|
||||
}
|
||||
|
||||
pVMap[nHeight + 1] = nHeight - 1;
|
||||
|
||||
for (nY = 0; nY < nHeight; nY++)
|
||||
{
|
||||
nGrey11 = pReadAcc->GetPixel(pVMap[nY], pHMap[0]).GetIndex();
|
||||
nGrey12 = pReadAcc->GetPixel(pVMap[nY], pHMap[1]).GetIndex();
|
||||
nGrey13 = pReadAcc->GetPixel(pVMap[nY], pHMap[2]).GetIndex();
|
||||
nGrey21 = pReadAcc->GetPixel(pVMap[nY + 1], pHMap[0]).GetIndex();
|
||||
nGrey22 = pReadAcc->GetPixel(pVMap[nY + 1], pHMap[1]).GetIndex();
|
||||
nGrey23 = pReadAcc->GetPixel(pVMap[nY + 1], pHMap[2]).GetIndex();
|
||||
nGrey31 = pReadAcc->GetPixel(pVMap[nY + 2], pHMap[0]).GetIndex();
|
||||
nGrey32 = pReadAcc->GetPixel(pVMap[nY + 2], pHMap[1]).GetIndex();
|
||||
nGrey33 = pReadAcc->GetPixel(pVMap[nY + 2], pHMap[2]).GetIndex();
|
||||
|
||||
Scanline pScanline = pWriteAcc->GetScanline(nY);
|
||||
for (nX = 0; nX < nWidth; nX++)
|
||||
{
|
||||
Bitmap aNewBmp(aBitmap.GetSizePixel(), vcl::PixelFormat::N8_BPP,
|
||||
&pReadAcc->GetPalette());
|
||||
BitmapScopedWriteAccess pWriteAcc(aNewBmp);
|
||||
nNx = nGrey11 + nGrey21 + nGrey31 - nGrey13 - nGrey23 - nGrey33;
|
||||
nNy = nGrey31 + nGrey32 + nGrey33 - nGrey11 - nGrey12 - nGrey13;
|
||||
|
||||
if (pWriteAcc)
|
||||
if (!nNx && !nNy)
|
||||
{
|
||||
BitmapColor aGrey(sal_uInt8(0));
|
||||
const sal_Int32 nWidth = pWriteAcc->Width();
|
||||
const sal_Int32 nHeight = pWriteAcc->Height();
|
||||
sal_Int32 nGrey11, nGrey12, nGrey13;
|
||||
sal_Int32 nGrey21, nGrey22, nGrey23;
|
||||
sal_Int32 nGrey31, nGrey32, nGrey33;
|
||||
double fAzim = basegfx::deg2rad<100>(mnAzimuthAngle100);
|
||||
double fElev = basegfx::deg2rad<100>(mnElevationAngle100);
|
||||
std::unique_ptr<sal_Int32[]> pHMap(new sal_Int32[nWidth + 2]);
|
||||
std::unique_ptr<sal_Int32[]> pVMap(new sal_Int32[nHeight + 2]);
|
||||
sal_Int32 nX, nY, nNx, nNy, nDotL;
|
||||
const sal_Int32 nLx = FRound(cos(fAzim) * cos(fElev) * 255.0);
|
||||
const sal_Int32 nLy = FRound(sin(fAzim) * cos(fElev) * 255.0);
|
||||
const sal_Int32 nLz = FRound(sin(fElev) * 255.0);
|
||||
const auto nZ2 = ((6 * 255) / 4) * ((6 * 255) / 4);
|
||||
const sal_Int32 nNzLz = ((6 * 255) / 4) * nLz;
|
||||
const sal_uInt8 cLz
|
||||
= static_cast<sal_uInt8>(std::clamp(nLz, sal_Int32(0), sal_Int32(255)));
|
||||
|
||||
// fill mapping tables
|
||||
pHMap[0] = 0;
|
||||
|
||||
for (nX = 1; nX <= nWidth; nX++)
|
||||
{
|
||||
pHMap[nX] = nX - 1;
|
||||
}
|
||||
|
||||
pHMap[nWidth + 1] = nWidth - 1;
|
||||
|
||||
pVMap[0] = 0;
|
||||
|
||||
for (nY = 1; nY <= nHeight; nY++)
|
||||
{
|
||||
pVMap[nY] = nY - 1;
|
||||
}
|
||||
|
||||
pVMap[nHeight + 1] = nHeight - 1;
|
||||
|
||||
for (nY = 0; nY < nHeight; nY++)
|
||||
{
|
||||
nGrey11 = pReadAcc->GetPixel(pVMap[nY], pHMap[0]).GetIndex();
|
||||
nGrey12 = pReadAcc->GetPixel(pVMap[nY], pHMap[1]).GetIndex();
|
||||
nGrey13 = pReadAcc->GetPixel(pVMap[nY], pHMap[2]).GetIndex();
|
||||
nGrey21 = pReadAcc->GetPixel(pVMap[nY + 1], pHMap[0]).GetIndex();
|
||||
nGrey22 = pReadAcc->GetPixel(pVMap[nY + 1], pHMap[1]).GetIndex();
|
||||
nGrey23 = pReadAcc->GetPixel(pVMap[nY + 1], pHMap[2]).GetIndex();
|
||||
nGrey31 = pReadAcc->GetPixel(pVMap[nY + 2], pHMap[0]).GetIndex();
|
||||
nGrey32 = pReadAcc->GetPixel(pVMap[nY + 2], pHMap[1]).GetIndex();
|
||||
nGrey33 = pReadAcc->GetPixel(pVMap[nY + 2], pHMap[2]).GetIndex();
|
||||
|
||||
Scanline pScanline = pWriteAcc->GetScanline(nY);
|
||||
for (nX = 0; nX < nWidth; nX++)
|
||||
{
|
||||
nNx = nGrey11 + nGrey21 + nGrey31 - nGrey13 - nGrey23 - nGrey33;
|
||||
nNy = nGrey31 + nGrey32 + nGrey33 - nGrey11 - nGrey12 - nGrey13;
|
||||
|
||||
if (!nNx && !nNy)
|
||||
{
|
||||
aGrey.SetIndex(cLz);
|
||||
}
|
||||
else if ((nDotL = nNx * nLx + nNy * nLy + nNzLz) < 0)
|
||||
{
|
||||
aGrey.SetIndex(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
const double fGrey
|
||||
= nDotL / sqrt(static_cast<double>(nNx * nNx + nNy * nNy + nZ2));
|
||||
aGrey.SetIndex(static_cast<sal_uInt8>(std::clamp(fGrey, 0.0, 255.0)));
|
||||
}
|
||||
|
||||
pWriteAcc->SetPixelOnData(pScanline, nX, aGrey);
|
||||
|
||||
if (nX < (nWidth - 1))
|
||||
{
|
||||
const sal_Int32 nNextX = pHMap[nX + 3];
|
||||
|
||||
nGrey11 = nGrey12;
|
||||
nGrey12 = nGrey13;
|
||||
nGrey13 = pReadAcc->GetPixel(pVMap[nY], nNextX).GetIndex();
|
||||
nGrey21 = nGrey22;
|
||||
nGrey22 = nGrey23;
|
||||
nGrey23 = pReadAcc->GetPixel(pVMap[nY + 1], nNextX).GetIndex();
|
||||
nGrey31 = nGrey32;
|
||||
nGrey32 = nGrey33;
|
||||
nGrey33 = pReadAcc->GetPixel(pVMap[nY + 2], nNextX).GetIndex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pHMap.reset();
|
||||
pVMap.reset();
|
||||
pWriteAcc.reset();
|
||||
bRet = true;
|
||||
aGrey.SetIndex(cLz);
|
||||
}
|
||||
else if ((nDotL = nNx * nLx + nNy * nLy + nNzLz) < 0)
|
||||
{
|
||||
aGrey.SetIndex(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
const double fGrey = nDotL / sqrt(static_cast<double>(nNx * nNx + nNy * nNy + nZ2));
|
||||
aGrey.SetIndex(static_cast<sal_uInt8>(std::clamp(fGrey, 0.0, 255.0)));
|
||||
}
|
||||
|
||||
pReadAcc.reset();
|
||||
pWriteAcc->SetPixelOnData(pScanline, nX, aGrey);
|
||||
|
||||
if (bRet)
|
||||
if (nX < (nWidth - 1))
|
||||
{
|
||||
const MapMode aMap(aBitmap.GetPrefMapMode());
|
||||
const Size aPrefSize(aBitmap.GetPrefSize());
|
||||
const sal_Int32 nNextX = pHMap[nX + 3];
|
||||
|
||||
aBitmap = aNewBmp;
|
||||
|
||||
aBitmap.SetPrefMapMode(aMap);
|
||||
aBitmap.SetPrefSize(aPrefSize);
|
||||
nGrey11 = nGrey12;
|
||||
nGrey12 = nGrey13;
|
||||
nGrey13 = pReadAcc->GetPixel(pVMap[nY], nNextX).GetIndex();
|
||||
nGrey21 = nGrey22;
|
||||
nGrey22 = nGrey23;
|
||||
nGrey23 = pReadAcc->GetPixel(pVMap[nY + 1], nNextX).GetIndex();
|
||||
nGrey31 = nGrey32;
|
||||
nGrey32 = nGrey33;
|
||||
nGrey33 = pReadAcc->GetPixel(pVMap[nY + 2], nNextX).GetIndex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bRet)
|
||||
return BitmapEx(aBitmap);
|
||||
pHMap.reset();
|
||||
pVMap.reset();
|
||||
pWriteAcc.reset();
|
||||
pReadAcc.reset();
|
||||
|
||||
return BitmapEx();
|
||||
const MapMode aMap(aBitmap.GetPrefMapMode());
|
||||
const Size aPrefSize(aBitmap.GetPrefSize());
|
||||
|
||||
aBitmap = aNewBmp;
|
||||
|
||||
aBitmap.SetPrefMapMode(aMap);
|
||||
aBitmap.SetPrefSize(aPrefSize);
|
||||
|
||||
return BitmapEx(aBitmap);
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
||||
@@ -1179,83 +1179,76 @@ static Bitmap DetectEdges( const Bitmap& rBmp )
|
||||
{
|
||||
constexpr sal_uInt8 cEdgeDetectThreshold = 128;
|
||||
const Size aSize( rBmp.GetSizePixel() );
|
||||
Bitmap aRetBmp;
|
||||
|
||||
if( ( aSize.Width() > 2 ) && ( aSize.Height() > 2 ) )
|
||||
if( ( aSize.Width() <= 2 ) || ( aSize.Height() <= 2 ) )
|
||||
return rBmp;
|
||||
|
||||
Bitmap aWorkBmp( rBmp );
|
||||
|
||||
if( !aWorkBmp.Convert( BmpConversion::N8BitGreys ) )
|
||||
return rBmp;
|
||||
|
||||
ScopedVclPtr<VirtualDevice> pVirDev(VclPtr<VirtualDevice>::Create());
|
||||
pVirDev->SetOutputSizePixel(aSize);
|
||||
Bitmap::ScopedReadAccess pReadAcc(aWorkBmp);
|
||||
if( !pReadAcc )
|
||||
return rBmp;
|
||||
|
||||
const tools::Long nWidth = aSize.Width();
|
||||
const tools::Long nWidth2 = nWidth - 2;
|
||||
const tools::Long nHeight = aSize.Height();
|
||||
const tools::Long nHeight2 = nHeight - 2;
|
||||
const tools::Long lThres2 = static_cast<tools::Long>(cEdgeDetectThreshold) * cEdgeDetectThreshold;
|
||||
tools::Long nSum1;
|
||||
tools::Long nSum2;
|
||||
tools::Long lGray;
|
||||
|
||||
// initialize border with white pixels
|
||||
pVirDev->SetLineColor( COL_WHITE );
|
||||
pVirDev->DrawLine( Point(), Point( nWidth - 1, 0L ) );
|
||||
pVirDev->DrawLine( Point( nWidth - 1, 0L ), Point( nWidth - 1, nHeight - 1 ) );
|
||||
pVirDev->DrawLine( Point( nWidth - 1, nHeight - 1 ), Point( 0L, nHeight - 1 ) );
|
||||
pVirDev->DrawLine( Point( 0, nHeight - 1 ), Point() );
|
||||
|
||||
for( tools::Long nY = 0, nY1 = 1, nY2 = 2; nY < nHeight2; nY++, nY1++, nY2++ )
|
||||
{
|
||||
Bitmap aWorkBmp( rBmp );
|
||||
|
||||
if( aWorkBmp.Convert( BmpConversion::N8BitGreys ) )
|
||||
Scanline pScanlineRead = pReadAcc->GetScanline( nY );
|
||||
Scanline pScanlineRead1 = pReadAcc->GetScanline( nY1 );
|
||||
Scanline pScanlineRead2 = pReadAcc->GetScanline( nY2 );
|
||||
for( tools::Long nX = 0, nXDst = 1, nXTmp; nX < nWidth2; nX++, nXDst++ )
|
||||
{
|
||||
bool bRet = false;
|
||||
nXTmp = nX;
|
||||
|
||||
ScopedVclPtr<VirtualDevice> pVirDev(VclPtr<VirtualDevice>::Create());
|
||||
pVirDev->SetOutputSizePixel(aSize);
|
||||
Bitmap::ScopedReadAccess pReadAcc(aWorkBmp);
|
||||
nSum2 = pReadAcc->GetIndexFromData( pScanlineRead, nXTmp++ );
|
||||
nSum1 = -nSum2;
|
||||
nSum2 += static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead, nXTmp++ )) << 1;
|
||||
lGray = pReadAcc->GetIndexFromData( pScanlineRead, nXTmp );
|
||||
nSum1 += lGray;
|
||||
nSum2 += lGray;
|
||||
|
||||
if( pReadAcc )
|
||||
{
|
||||
const tools::Long nWidth = aSize.Width();
|
||||
const tools::Long nWidth2 = nWidth - 2;
|
||||
const tools::Long nHeight = aSize.Height();
|
||||
const tools::Long nHeight2 = nHeight - 2;
|
||||
const tools::Long lThres2 = static_cast<tools::Long>(cEdgeDetectThreshold) * cEdgeDetectThreshold;
|
||||
tools::Long nSum1;
|
||||
tools::Long nSum2;
|
||||
tools::Long lGray;
|
||||
nSum1 += static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead1, nXTmp )) << 1;
|
||||
nXTmp -= 2;
|
||||
nSum1 -= static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead1, nXTmp )) << 1;
|
||||
|
||||
// initialize border with white pixels
|
||||
pVirDev->SetLineColor( COL_WHITE );
|
||||
pVirDev->DrawLine( Point(), Point( nWidth - 1, 0L ) );
|
||||
pVirDev->DrawLine( Point( nWidth - 1, 0L ), Point( nWidth - 1, nHeight - 1 ) );
|
||||
pVirDev->DrawLine( Point( nWidth - 1, nHeight - 1 ), Point( 0L, nHeight - 1 ) );
|
||||
pVirDev->DrawLine( Point( 0, nHeight - 1 ), Point() );
|
||||
lGray = -static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead2, nXTmp++ ));
|
||||
nSum1 += lGray;
|
||||
nSum2 += lGray;
|
||||
nSum2 -= static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead2, nXTmp++ )) << 1;
|
||||
lGray = static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead2, nXTmp ));
|
||||
nSum1 += lGray;
|
||||
nSum2 -= lGray;
|
||||
|
||||
for( tools::Long nY = 0, nY1 = 1, nY2 = 2; nY < nHeight2; nY++, nY1++, nY2++ )
|
||||
{
|
||||
Scanline pScanlineRead = pReadAcc->GetScanline( nY );
|
||||
Scanline pScanlineRead1 = pReadAcc->GetScanline( nY1 );
|
||||
Scanline pScanlineRead2 = pReadAcc->GetScanline( nY2 );
|
||||
for( tools::Long nX = 0, nXDst = 1, nXTmp; nX < nWidth2; nX++, nXDst++ )
|
||||
{
|
||||
nXTmp = nX;
|
||||
|
||||
nSum2 = pReadAcc->GetIndexFromData( pScanlineRead, nXTmp++ );
|
||||
nSum1 = -nSum2;
|
||||
nSum2 += static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead, nXTmp++ )) << 1;
|
||||
lGray = pReadAcc->GetIndexFromData( pScanlineRead, nXTmp );
|
||||
nSum1 += lGray;
|
||||
nSum2 += lGray;
|
||||
|
||||
nSum1 += static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead1, nXTmp )) << 1;
|
||||
nXTmp -= 2;
|
||||
nSum1 -= static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead1, nXTmp )) << 1;
|
||||
|
||||
lGray = -static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead2, nXTmp++ ));
|
||||
nSum1 += lGray;
|
||||
nSum2 += lGray;
|
||||
nSum2 -= static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead2, nXTmp++ )) << 1;
|
||||
lGray = static_cast<tools::Long>(pReadAcc->GetIndexFromData( pScanlineRead2, nXTmp ));
|
||||
nSum1 += lGray;
|
||||
nSum2 -= lGray;
|
||||
|
||||
if( ( nSum1 * nSum1 + nSum2 * nSum2 ) < lThres2 )
|
||||
pVirDev->DrawPixel( Point(nXDst, nY), COL_WHITE );
|
||||
else
|
||||
pVirDev->DrawPixel( Point(nXDst, nY), COL_BLACK );
|
||||
}
|
||||
}
|
||||
|
||||
bRet = true;
|
||||
}
|
||||
|
||||
pReadAcc.reset();
|
||||
|
||||
if( bRet )
|
||||
aRetBmp = pVirDev->GetBitmap(Point(0,0), aSize);
|
||||
if( ( nSum1 * nSum1 + nSum2 * nSum2 ) < lThres2 )
|
||||
pVirDev->DrawPixel( Point(nXDst, nY), COL_WHITE );
|
||||
else
|
||||
pVirDev->DrawPixel( Point(nXDst, nY), COL_BLACK );
|
||||
}
|
||||
}
|
||||
|
||||
pReadAcc.reset();
|
||||
|
||||
Bitmap aRetBmp = pVirDev->GetBitmap(Point(0,0), aSize);
|
||||
|
||||
if( aRetBmp.IsEmpty() )
|
||||
aRetBmp = rBmp;
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user