vcl/source/bitmap/BitmapColorQuantizationFilter.cxx | 313 +++++++++----------- vcl/source/bitmap/BitmapConvolutionMatrixFilter.cxx | 294 +++++++++--------- vcl/source/bitmap/BitmapEmbossGreyFilter.cxx | 213 ++++++------- vcl/source/bitmap/BitmapEx.cxx | 135 ++++---- 4 files changed, 448 insertions(+), 507 deletions(-)
New commits: commit 0461eb7564236b8a427fe677658705e9955a8d13 Author: Noel Grandin <noelgran...@gmail.com> AuthorDate: Wed Jan 4 19:03:29 2023 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Thu Jan 5 17:00:54 2023 +0000 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.gran...@collabora.co.uk> diff --git a/vcl/source/bitmap/BitmapColorQuantizationFilter.cxx b/vcl/source/bitmap/BitmapColorQuantizationFilter.cxx index 45d39add373d..cef8fb60b6f9 100644 --- a/vcl/source/bitmap/BitmapColorQuantizationFilter.cxx +++ b/vcl/source/bitmap/BitmapColorQuantizationFilter.cxx @@ -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++; - } - } + pCountTable[nIndex].mnIndex = nIndex; + nIndex++; } + } + } - if (pRAcc->HasPalette()) + if (pRAcc->HasPalette()) + { + for (sal_Int32 nY = 0; nY < nHeight; nY++) + { + Scanline pScanlineRead = pRAcc->GetScanline(nY); + for (sal_Int32 nX = 0; nX < nWidth; nX++) { - 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++; - } - } + 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 + } + } + else + { + for (sal_Int32 nY = 0; nY < nHeight; nY++) + { + Scanline pScanlineRead = pRAcc->GetScanline(nY); + for (sal_Int32 nX = 0; nX < nWidth; nX++) { - 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++; - } - } + 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); + BitmapPalette aNewPal(cappedNewColorCount); - std::qsort(pCountTable.get(), nTotalColors, sizeof(PopularColorCount), - [](const void* p1, const void* p2) { - int nRet; + 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; + 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; - }); + 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)); - } + 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(); - Bitmap aNewBmp(aBitmap.GetSizePixel(), vcl::PixelFormat::N8_BPP, &aNewPal); - BitmapScopedWriteAccess pWAcc(aNewBmp); + BitmapColor aDstCol(sal_uInt8(0)); + std::unique_ptr<sal_uInt8[]> pIndexMap(new sal_uInt8[nTotalColors]); - if (pWAcc) + 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) { - 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; + pIndexMap[nIndex++] = static_cast<sal_uInt8>(aNewPal.GetBestIndex( + BitmapColor(static_cast<sal_uInt8>(nR), static_cast<sal_uInt8>(nG), + static_cast<sal_uInt8>(nB)))); } + } + } - pCountTable.reset(); - pRAcc.reset(); - - if (bRet) + 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 MapMode aMap(aBitmap.GetPrefMapMode()); - const Size aSize(aBitmap.GetPrefSize()); - - aBitmap = aNewBmp; + 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); - aBitmap.SetPrefMapMode(aMap); - aBitmap.SetPrefSize(aSize); + 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); } } } - if (bRet) - return BitmapEx(aBitmap); + 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(); + return BitmapEx(aBitmap); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/bitmap/BitmapConvolutionMatrixFilter.cxx b/vcl/source/bitmap/BitmapConvolutionMatrixFilter.cxx index db68bff1de38..39b8cf4cc18d 100644 --- a/vcl/source/bitmap/BitmapConvolutionMatrixFilter.cxx +++ b/vcl/source/bitmap/BitmapConvolutionMatrixFilter.cxx @@ -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(); + + 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++) + { + 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]; - if (pReadAcc) + // create row LUT + for (i = 0; i < nHeight2; i++) { - Bitmap aNewBmp(aBitmap.GetSizePixel(), vcl::PixelFormat::N24_BPP); - BitmapScopedWriteAccess pWriteAcc(aNewBmp); + 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]); + } - if (pWriteAcc) + // do convolution + for (nY = 0; nY < nHeight;) + { + Scanline pScanline = pWriteAcc->GetScanline(nY); + for (nX = 0; nX < nWidth; nX++) { - 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; - } - } + // 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)))); + } - // create column LUT - for (i = 0; i < nWidth2; i++) + if (++nY < nHeight) + { + if (pRowTmp1 == pColRow1.get()) { - pColm[i] = (i > 0) ? (i - 1) : 0; + pRowTmp1 = pColRow2.get(); + pRowTmp2 = pColRow3.get(); + pRowTmp3 = pColRow1.get(); } - - pColm[nWidth + 1] = pColm[nWidth]; - - // create row LUT - for (i = 0; i < nHeight2; i++) + else if (pRowTmp1 == pColRow2.get()) { - pRows[i] = (i > 0) ? (i - 1) : 0; + pRowTmp1 = pColRow3.get(); + pRowTmp2 = pColRow1.get(); + pRowTmp3 = pColRow2.get(); } - - pRows[nHeight + 1] = pRows[nHeight]; - - // read first three rows of bitmap color - for (i = 0; i < nWidth2; i++) + else { - pColRow1[i] = pReadAcc->GetColor(pRows[0], pColm[i]); - pColRow2[i] = pReadAcc->GetColor(pRows[1], pColm[i]); - pColRow3[i] = pReadAcc->GetColor(pRows[2], pColm[i]); + pRowTmp1 = pColRow1.get(); + pRowTmp2 = pColRow2.get(); + pRowTmp3 = pColRow3.get(); } - // do convolution - for (nY = 0; nY < nHeight;) + for (i = 0; i < nWidth2; i++) { - 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]); - } - } + 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()); + pWriteAcc.reset(); + pReadAcc.reset(); - aBitmap = aNewBmp; + const MapMode aMap(aBitmap.GetPrefMapMode()); + const Size aPrefSize(aBitmap.GetPrefSize()); - aBitmap.SetPrefMapMode(aMap); - aBitmap.SetPrefSize(aPrefSize); - } - } + aBitmap = aNewBmp; - if (bRet) - return BitmapEx(aBitmap); + aBitmap.SetPrefMapMode(aMap); + aBitmap.SetPrefSize(aPrefSize); - return BitmapEx(); + return BitmapEx(aBitmap); } const sal_Int32 g_SharpenMatrix[] = { -1, -1, -1, -1, 16, -1, -1, -1, -1 }; diff --git a/vcl/source/bitmap/BitmapEmbossGreyFilter.cxx b/vcl/source/bitmap/BitmapEmbossGreyFilter.cxx index a8705176f1d1..f8b974a4367f 100644 --- a/vcl/source/bitmap/BitmapEmbossGreyFilter.cxx +++ b/vcl/source/bitmap/BitmapEmbossGreyFilter.cxx @@ -24,137 +24,120 @@ BitmapEx BitmapEmbossGreyFilter::execute(BitmapEx const& rBitmapEx) const { Bitmap aBitmap(rBitmapEx.GetBitmap()); - bool bRet = aBitmap.ImplMakeGreyscales(); + if (!aBitmap.ImplMakeGreyscales()) + return BitmapEx(); + + 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++) + { + pHMap[nX] = nX - 1; + } + + pHMap[nWidth + 1] = nWidth - 1; + + pVMap[0] = 0; - if (bRet) + for (nY = 1; nY <= nHeight; nY++) { - bRet = false; + pVMap[nY] = nY - 1; + } - Bitmap::ScopedReadAccess pReadAcc(aBitmap); + pVMap[nHeight + 1] = nHeight - 1; - if (pReadAcc) + 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); } - - pReadAcc.reset(); - - if (bRet) + else if ((nDotL = nNx * nLx + nNy * nLy + nNzLz) < 0) { - const MapMode aMap(aBitmap.GetPrefMapMode()); - const Size aPrefSize(aBitmap.GetPrefSize()); + 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))); + } - aBitmap = aNewBmp; + pWriteAcc->SetPixelOnData(pScanline, nX, aGrey); - aBitmap.SetPrefMapMode(aMap); - aBitmap.SetPrefSize(aPrefSize); + 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(); } } } - if (bRet) - return BitmapEx(aBitmap); + pHMap.reset(); + pVMap.reset(); + pWriteAcc.reset(); + pReadAcc.reset(); + + const MapMode aMap(aBitmap.GetPrefMapMode()); + const Size aPrefSize(aBitmap.GetPrefSize()); + + aBitmap = aNewBmp; + + aBitmap.SetPrefMapMode(aMap); + aBitmap.SetPrefSize(aPrefSize); - return BitmapEx(); + return BitmapEx(aBitmap); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/bitmap/BitmapEx.cxx b/vcl/source/bitmap/BitmapEx.cxx index 6ff2280cdb06..a770f2acfc8d 100644 --- a/vcl/source/bitmap/BitmapEx.cxx +++ b/vcl/source/bitmap/BitmapEx.cxx @@ -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; - - ScopedVclPtr<VirtualDevice> pVirDev(VclPtr<VirtualDevice>::Create()); - pVirDev->SetOutputSizePixel(aSize); - Bitmap::ScopedReadAccess pReadAcc(aWorkBmp); - - 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; - - // 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++ ) - { - 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); + 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 ); } } + pReadAcc.reset(); + + Bitmap aRetBmp = pVirDev->GetBitmap(Point(0,0), aSize); + if( aRetBmp.IsEmpty() ) aRetBmp = rBmp; else