diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /vcl/source/bitmap/BitmapMosaicFilter.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vcl/source/bitmap/BitmapMosaicFilter.cxx')
-rw-r--r-- | vcl/source/bitmap/BitmapMosaicFilter.cxx | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/vcl/source/bitmap/BitmapMosaicFilter.cxx b/vcl/source/bitmap/BitmapMosaicFilter.cxx new file mode 100644 index 000000000..a146a142b --- /dev/null +++ b/vcl/source/bitmap/BitmapMosaicFilter.cxx @@ -0,0 +1,186 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#include <vcl/bitmap.hxx> +#include <vcl/bitmapex.hxx> +#include <vcl/BitmapMosaicFilter.hxx> + +#include <bitmap/BitmapWriteAccess.hxx> + +BitmapEx BitmapMosaicFilter::execute(BitmapEx const& rBitmapEx) const +{ + Bitmap aBitmap(rBitmapEx.GetBitmap()); + + bool bRet = false; + + if (mnTileWidth > 1 || mnTileHeight > 1) + { + std::unique_ptr<Bitmap> pNewBmp; + BitmapReadAccess* pReadAcc; + BitmapWriteAccess* pWriteAcc; + + if (!isPalettePixelFormat(aBitmap.getPixelFormat())) + { + pReadAcc = pWriteAcc = aBitmap.AcquireWriteAccess(); + } + else + { + pNewBmp.reset(new Bitmap(aBitmap.GetSizePixel(), vcl::PixelFormat::N24_BPP)); + pReadAcc = aBitmap.AcquireReadAccess(); + pWriteAcc = pNewBmp->AcquireWriteAccess(); + } + + bool bConditionsMet = false; + sal_Int32 nWidth(0); + sal_Int32 nHeight(0); + if (pReadAcc && pWriteAcc) + { + nWidth = pReadAcc->Width(); + nHeight = pReadAcc->Height(); + bConditionsMet = (nWidth > 0 && nHeight > 0); + } + + if (bConditionsMet) + { + BitmapColor aCol; + sal_Int32 nX, nY, nX1, nX2, nY1, nY2, nSumR, nSumG, nSumB; + double fArea_1; + + nY1 = 0; + nY2 = mnTileHeight - 1; + + if (nY2 >= nHeight) + nY2 = nHeight - 1; + + do + { + nX1 = 0; + nX2 = mnTileWidth - 1; + + if (nX2 >= nWidth) + nX2 = nWidth - 1; + + fArea_1 = 1.0 / ((nX2 - nX1 + 1) * (nY2 - nY1 + 1)); + + if (!pNewBmp) + { + do + { + for (nY = nY1, nSumR = nSumG = nSumB = 0; nY <= nY2; nY++) + { + Scanline pScanlineRead = pReadAcc->GetScanline(nY); + for (nX = nX1; nX <= nX2; nX++) + { + aCol = pReadAcc->GetPixelFromData(pScanlineRead, nX); + nSumR += aCol.GetRed(); + nSumG += aCol.GetGreen(); + nSumB += aCol.GetBlue(); + } + } + + aCol.SetRed(static_cast<sal_uInt8>(nSumR * fArea_1)); + aCol.SetGreen(static_cast<sal_uInt8>(nSumG * fArea_1)); + aCol.SetBlue(static_cast<sal_uInt8>(nSumB * fArea_1)); + + for (nY = nY1; nY <= nY2; nY++) + { + Scanline pScanline = pWriteAcc->GetScanline(nY); + for (nX = nX1; nX <= nX2; nX++) + pWriteAcc->SetPixelOnData(pScanline, nX, aCol); + } + + nX1 += mnTileWidth; + nX2 += mnTileWidth; + + if (nX2 >= nWidth) + { + nX2 = nWidth - 1; + fArea_1 = 1.0 / ((nX2 - nX1 + 1) * (nY2 - nY1 + 1)); + } + } while (nX1 < nWidth); + } + else + { + do + { + for (nY = nY1, nSumR = nSumG = nSumB = 0; nY <= nY2; nY++) + { + Scanline pScanlineRead = pReadAcc->GetScanline(nY); + for (nX = nX1; nX <= nX2; nX++) + { + const BitmapColor& rCol = pReadAcc->GetPaletteColor( + pReadAcc->GetIndexFromData(pScanlineRead, nX)); + nSumR += rCol.GetRed(); + nSumG += rCol.GetGreen(); + nSumB += rCol.GetBlue(); + } + } + + aCol.SetRed(static_cast<sal_uInt8>(nSumR * fArea_1)); + aCol.SetGreen(static_cast<sal_uInt8>(nSumG * fArea_1)); + aCol.SetBlue(static_cast<sal_uInt8>(nSumB * fArea_1)); + + for (nY = nY1; nY <= nY2; nY++) + { + Scanline pScanline = pWriteAcc->GetScanline(nY); + for (nX = nX1; nX <= nX2; nX++) + pWriteAcc->SetPixelOnData(pScanline, nX, aCol); + } + + nX1 += mnTileWidth; + nX2 += mnTileWidth; + + if (nX2 >= nWidth) + { + nX2 = nWidth - 1; + fArea_1 = 1.0 / ((nX2 - nX1 + 1) * (nY2 - nY1 + 1)); + } + } while (nX1 < nWidth); + } + + nY1 += mnTileHeight; + nY2 += mnTileHeight; + + if (nY2 >= nHeight) + nY2 = nHeight - 1; + + } while (nY1 < nHeight); + + bRet = true; + } + + if (pWriteAcc == pReadAcc) + pWriteAcc = nullptr; + Bitmap::ReleaseAccess(pReadAcc); + + if (pNewBmp) + { + Bitmap::ReleaseAccess(pWriteAcc); + + if (bRet) + { + const MapMode aMap(aBitmap.GetPrefMapMode()); + const Size aPrefSize(aBitmap.GetPrefSize()); + + aBitmap = *pNewBmp; + + aBitmap.SetPrefMapMode(aMap); + aBitmap.SetPrefSize(aPrefSize); + } + } + } + + if (bRet) + return BitmapEx(aBitmap); + + return BitmapEx(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |