diff options
author | Chris Sherlock <chris.sherlock79@gmail.com> | 2018-04-20 20:39:48 +1000 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2018-04-22 05:34:03 +0200 |
commit | 63a716783a555e91ad3a32f25f20cffc88ca15e4 (patch) | |
tree | 2bf6256e570d94af1d16e01f2c44d1c71630fe9b /vcl | |
parent | 1ab12471f3a69c4d502e6271e84ddf8a981f507f (diff) |
vcl: ImplMosaic() -> BitmapMosaicFilter
Change-Id: Ia0910ae9166c4eb6b870ab25db761bc1703fec68
Reviewed-on: https://gerrit.libreoffice.org/53203
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/Library_vcl.mk | 1 | ||||
-rw-r--r-- | vcl/source/bitmap/BitmapMosaicFilter.cxx | 187 | ||||
-rw-r--r-- | vcl/source/gdi/bitmap4.cxx | 183 |
3 files changed, 197 insertions, 174 deletions
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(); |