include/vcl/BitmapMosaicFilter.hxx | 36 +++++ include/vcl/bitmap.hxx | 1 vcl/Library_vcl.mk | 1 vcl/source/bitmap/BitmapMosaicFilter.cxx | 187 +++++++++++++++++++++++++++++++ vcl/source/gdi/bitmap4.cxx | 183 +----------------------------- 5 files changed, 233 insertions(+), 175 deletions(-)
New commits: commit 63a716783a555e91ad3a32f25f20cffc88ca15e4 Author: Chris Sherlock <[email protected]> Date: Fri Apr 20 20:39:48 2018 +1000 vcl: ImplMosaic() -> BitmapMosaicFilter Change-Id: Ia0910ae9166c4eb6b870ab25db761bc1703fec68 Reviewed-on: https://gerrit.libreoffice.org/53203 Tested-by: Jenkins <[email protected]> Reviewed-by: Tomaž Vajngerl <[email protected]> diff --git a/include/vcl/BitmapMosaicFilter.hxx b/include/vcl/BitmapMosaicFilter.hxx new file mode 100644 index 000000000000..0fbf19613b5f --- /dev/null +++ b/include/vcl/BitmapMosaicFilter.hxx @@ -0,0 +1,36 @@ +/* -*- 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/. + * + */ + +#ifndef INCLUDED_VCL_BITMAPMOSAICFILTER_HXX +#define INCLUDED_VCL_BITMAPMOSAICFILTER_HXX + +#include <vcl/BitmapFilter.hxx> + +class BitmapEx; + +class VCL_DLLPUBLIC BitmapMosaicFilter : public BitmapFilter +{ +public: + BitmapMosaicFilter(sal_uLong nTileWidth, sal_uLong nTileHeight) + : mnTileWidth(nTileWidth) + , mnTileHeight(nTileHeight) + { + } + + virtual BitmapEx execute(BitmapEx const& rBitmapEx) override; + +private: + sal_uLong mnTileWidth; + sal_uLong mnTileHeight; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/vcl/bitmap.hxx b/include/vcl/bitmap.hxx index b71f8a4224ba..2c1621041d7a 100644 --- a/include/vcl/bitmap.hxx +++ b/include/vcl/bitmap.hxx @@ -659,7 +659,6 @@ public: SAL_DLLPRIVATE bool ImplDitherFloyd16(); SAL_DLLPRIVATE bool ImplEmbossGrey( const BmpFilterParam* pFilterParam ); - SAL_DLLPRIVATE bool ImplMosaic( const BmpFilterParam* pFilterParam ); SAL_DLLPRIVATE bool ImplDuotoneFilter( const sal_uLong nColorOne, sal_uLong nColorTwo ); public: diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 82f67dd845b9..49044708edd3 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -315,6 +315,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/bitmap/BitmapSobelGreyFilter \ vcl/source/bitmap/BitmapSolarizeFilter \ vcl/source/bitmap/BitmapSepiaFilter \ + vcl/source/bitmap/BitmapMosaicFilter \ vcl/source/bitmap/BitmapPopArtFilter \ vcl/source/bitmap/BitmapConvolutionMatrixFilter \ vcl/source/bitmap/BitmapMedianFilter \ diff --git a/vcl/source/bitmap/BitmapMosaicFilter.cxx b/vcl/source/bitmap/BitmapMosaicFilter.cxx new file mode 100644 index 000000000000..faefbe5d3766 --- /dev/null +++ b/vcl/source/bitmap/BitmapMosaicFilter.cxx @@ -0,0 +1,187 @@ +/* -*- 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/bitmapaccess.hxx> +#include <vcl/BitmapMosaicFilter.hxx> + +#include <bitmapwriteaccess.hxx> + +BitmapEx BitmapMosaicFilter::execute(BitmapEx const& rBitmapEx) +{ + Bitmap aBitmap(rBitmapEx.GetBitmap()); + + bool bRet = false; + + if (!mnTileWidth) + mnTileWidth = 1; + + if (!mnTileHeight) + mnTileHeight = 1; + + if (mnTileWidth > 1 || mnTileHeight > 1) + { + Bitmap* pNewBmp; + BitmapReadAccess* pReadAcc; + BitmapWriteAccess* pWriteAcc; + + if (aBitmap.GetBitCount() > 8) + { + pNewBmp = nullptr; + pReadAcc = pWriteAcc = aBitmap.AcquireWriteAccess(); + } + else + { + pNewBmp = new Bitmap(aBitmap.GetSizePixel(), 24); + pReadAcc = aBitmap.AcquireReadAccess(); + pWriteAcc = pNewBmp->AcquireWriteAccess(); + } + + bool bConditionsMet = false; + long nWidth(0); + long nHeight(0); + if (pReadAcc && pWriteAcc) + { + nWidth = pReadAcc->Width(); + nHeight = pReadAcc->Height(); + bConditionsMet = (nWidth > 0 && nHeight > 0); + } + + if (bConditionsMet) + { + BitmapColor aCol; + long 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; + } + + Bitmap::ReleaseAccess(pReadAcc); + + if (bRet) + { + const MapMode aMap(aBitmap.GetPrefMapMode()); + const Size aPrefSize(aBitmap.GetPrefSize()); + + aBitmap = *pNewBmp; + + aBitmap.SetPrefMapMode(aMap); + aBitmap.SetPrefSize(aPrefSize); + } + } + + if (bRet) + return BitmapEx(rBitmapEx); + + return BitmapEx(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/gdi/bitmap4.cxx b/vcl/source/gdi/bitmap4.cxx index ea8fec2d4d49..2933ebd21a66 100644 --- a/vcl/source/gdi/bitmap4.cxx +++ b/vcl/source/gdi/bitmap4.cxx @@ -26,6 +26,8 @@ #include <vcl/BitmapSobelGreyFilter.hxx> #include <vcl/BitmapSolarizeFilter.hxx> #include <vcl/BitmapSepiaFilter.hxx> +#include <vcl/BitmapMosaicFilter.hxx> +#include <vcl/BitmapSepiaFilter.hxx> #include <vcl/BitmapPopArtFilter.hxx> #include <bitmapwriteaccess.hxx> @@ -96,7 +98,13 @@ bool Bitmap::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam ) break; case BmpFilter::Mosaic: - bRet = ImplMosaic( pFilterParam ); + { + BitmapEx aBmpEx(*this); + bRet = BitmapFilter::Filter(aBmpEx, BitmapMosaicFilter(pFilterParam->maMosaicTileSize.mnTileWidth, + pFilterParam->maMosaicTileSize.mnTileHeight)); + *this = aBmpEx.GetBitmap(); + } + break; case BmpFilter::EmbossGrey: @@ -236,179 +244,6 @@ bool Bitmap::ImplEmbossGrey( const BmpFilterParam* pFilterParam ) return bRet; } -bool Bitmap::ImplMosaic( const BmpFilterParam* pFilterParam ) -{ - sal_uLong nTileWidth = ( pFilterParam && pFilterParam->meFilter == BmpFilter::Mosaic ) ? - pFilterParam->maMosaicTileSize.mnTileWidth : 4; - sal_uLong nTileHeight = ( pFilterParam && pFilterParam->meFilter == BmpFilter::Mosaic ) ? - pFilterParam->maMosaicTileSize.mnTileHeight : 4; - bool bRet = false; - - if( !nTileWidth ) - nTileWidth = 1; - - if( !nTileHeight ) - nTileHeight = 1; - - if( nTileWidth > 1 || nTileHeight > 1 ) - { - Bitmap* pNewBmp; - BitmapReadAccess* pReadAcc; - BitmapWriteAccess* pWriteAcc; - - if( GetBitCount() > 8 ) - { - pNewBmp = nullptr; - pReadAcc = pWriteAcc = AcquireWriteAccess(); - } - else - { - pNewBmp = new Bitmap( GetSizePixel(), 24 ); - pReadAcc = AcquireReadAccess(); - pWriteAcc = pNewBmp->AcquireWriteAccess(); - } - - bool bConditionsMet = false; - long nWidth(0); - long nHeight(0); - if (pReadAcc && pWriteAcc) - { - nWidth = pReadAcc->Width(); - nHeight = pReadAcc->Height(); - bConditionsMet = (nWidth > 0 && nHeight > 0); - } - - if (bConditionsMet) - { - BitmapColor aCol; - long nX, nY, nX1, nX2, nY1, nY2, nSumR, nSumG, nSumB; - double fArea_1; - - nY1 = 0; nY2 = nTileHeight - 1; - - if( nY2 >= nHeight ) - nY2 = nHeight - 1; - - do - { - nX1 = 0; nX2 = nTileWidth - 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 += nTileWidth; nX2 += nTileWidth; - - 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 += nTileWidth; nX2 += nTileWidth; - - if( nX2 >= nWidth ) - { - nX2 = nWidth - 1; - fArea_1 = 1.0 / ( ( nX2 - nX1 + 1 ) * ( nY2 - nY1 + 1 ) ); - } - } - while( nX1 < nWidth ); - } - - nY1 += nTileHeight; nY2 += nTileHeight; - - if( nY2 >= nHeight ) - nY2 = nHeight - 1; - } - while( nY1 < nHeight ); - - bRet = true; - } - - ReleaseAccess( pReadAcc ); - - if( pNewBmp ) - { - Bitmap::ReleaseAccess( pWriteAcc ); - - if( bRet ) - { - const MapMode aMap( maPrefMapMode ); - const Size aSize( maPrefSize ); - - *this = *pNewBmp; - - maPrefMapMode = aMap; - maPrefSize = aSize; - } - - delete pNewBmp; - } - } - else - bRet = true; - - return bRet; -} - bool Bitmap::ImplDuotoneFilter( const sal_uLong nColorOne, const sal_uLong nColorTwo ) { const long nWidth = GetSizePixel().Width(); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
