From 1f6af5c409105562edf2a034f4841c1aeb5a38b5 Mon Sep 17 00:00:00 2001 From: Chris Sherlock Date: Sun, 22 Apr 2018 22:33:40 +1000 Subject: vcl: move Bitmap::MakeMonochrome() to BitmapMonochromeFilter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iefe5be4349475a4aa0138534cf6bfe87ff7df245 Reviewed-on: https://gerrit.libreoffice.org/53280 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl --- canvas/source/vcl/canvashelper.cxx | 6 +- canvas/source/vcl/spritehelper.cxx | 5 +- include/vcl/BitmapMonochromeFilter.hxx | 45 ++++++++++++ include/vcl/bitmap.hxx | 24 ++----- vcl/Library_vcl.mk | 13 ++-- vcl/qa/cppunit/BitmapTest.cxx | 5 +- vcl/source/bitmap/BitmapMonochromeFilter.cxx | 101 +++++++++++++++++++++++++++ vcl/source/bitmap/bitmap.cxx | 76 -------------------- vcl/source/gdi/bitmap3.cxx | 7 +- vcl/source/gdi/bitmapex.cxx | 14 +++- vcl/source/outdev/bitmap.cxx | 7 +- 11 files changed, 191 insertions(+), 112 deletions(-) create mode 100644 include/vcl/BitmapMonochromeFilter.hxx create mode 100644 vcl/source/bitmap/BitmapMonochromeFilter.cxx diff --git a/canvas/source/vcl/canvashelper.cxx b/canvas/source/vcl/canvashelper.cxx index d31a45286dc3..5a0a74e389d2 100644 --- a/canvas/source/vcl/canvashelper.cxx +++ b/canvas/source/vcl/canvashelper.cxx @@ -46,6 +46,7 @@ #include #include #include +#include #include @@ -720,8 +721,9 @@ namespace vclcanvas if( aBmpEx.IsAlpha() ) { Bitmap aMask( aBmpEx.GetAlpha().GetBitmap() ); - aMask.MakeMonochrome(253); - aBmpEx = BitmapEx( aBmpEx.GetBitmap(), aMask ); + BitmapEx aMaskEx(aMask); + BitmapFilter::Filter(aMaskEx, BitmapMonochromeFilter(253)); + aMask = aMaskEx.GetBitmap(); } else if( aBmpEx.IsTransparent() ) { diff --git a/canvas/source/vcl/spritehelper.cxx b/canvas/source/vcl/spritehelper.cxx index 366d0a5b9829..9424d4ec54b9 100644 --- a/canvas/source/vcl/spritehelper.cxx +++ b/canvas/source/vcl/spritehelper.cxx @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -153,7 +154,9 @@ namespace vclcanvas { OSL_FAIL("CanvasCustomSprite::redraw(): Mask bitmap is not " "monochrome (performance!)"); - aMask.MakeMonochrome(255); + BitmapEx aMaskEx(aMask); + BitmapFilter::Filter(aMaskEx, BitmapMonochromeFilter(255)); + aMask = aMaskEx.GetBitmap(); } #endif diff --git a/include/vcl/BitmapMonochromeFilter.hxx b/include/vcl/BitmapMonochromeFilter.hxx new file mode 100644 index 000000000000..acbcc3cc9b2c --- /dev/null +++ b/include/vcl/BitmapMonochromeFilter.hxx @@ -0,0 +1,45 @@ +/* -*- 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_INCLUDE_VCL_BITMAPMONOCHROMEFILTER_HXX +#define INCLUDED_INCLUDE_VCL_BITMAPMONOCHROMEFILTER_HXX + +#include + +#include + +class VCL_DLLPUBLIC BitmapMonochromeFilter : public BitmapFilter +{ +public: + /** Convert to 2 color bitmap. + + Converts to a 2 color indexed bitmap - note that we don't change to black + and white monochrome, but we pick the closest color to black and white in + the bitmap. + + @param cThreshold + Luminance value that determines whether the colour should be black (or + closest color to black) or white (or closest color to white). + + */ + BitmapMonochromeFilter(sal_uInt8 cThreshold) + : mcThreshold(cThreshold) + { + } + + virtual BitmapEx execute(BitmapEx const& rBitmapEx) override; + +private: + sal_uInt8 mcThreshold; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/vcl/bitmap.hxx b/include/vcl/bitmap.hxx index 6ba6dd43378c..aa330fde9877 100644 --- a/include/vcl/bitmap.hxx +++ b/include/vcl/bitmap.hxx @@ -177,28 +177,14 @@ public: */ bool Convert( BmpConversion eConversion ); - - /** Convert to 2 color bitmap. - - Converts to a 2 color indexed bitmap - note that we don't change to black and white - monochrome, but we pick the closest color to black and white in the bitmap. - - @param cThreshold - Luminance value that determines whether the colour should be black (or closest - color to black) or white (or closest color to white). - - @return true conversion to monochrome bitmap was successful - */ - bool MakeMonochrome(sal_uInt8 cThreshold); - /** Apply a dither algorithm to the bitmap - This method dithers the bitmap inplace, i.e. a true color - bitmap is converted to a paletted bitmap, reducing the color - deviation by error diffusion. + This method dithers the bitmap inplace, i.e. a true color + bitmap is converted to a paletted bitmap, reducing the color + deviation by error diffusion. - @param nDitherFlags - The algorithm to be used for dithering + @param nDitherFlags + The algorithm to be used for dithering */ bool Dither( BmpDitherFlags nDitherFlags ); diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 123d8e80fd7d..8ea16175dc55 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -311,6 +311,13 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/graphic/UnoGraphicTransformer \ vcl/source/bitmap/bitmap \ vcl/source/bitmap/bitmapfilter \ + vcl/source/bitmap/BitmapMonochromeFilter \ + vcl/source/bitmap/BitmapSmoothenFilter \ + vcl/source/bitmap/BitmapLightenFilter \ + vcl/source/bitmap/BitmapDisabledImageFilter \ + vcl/source/bitmap/BitmapColorizeFilter \ + vcl/source/bitmap/bitmappaint \ + vcl/source/bitmap/BitmapGaussianSeparableBlurFilter \ vcl/source/bitmap/BitmapSobelGreyFilter \ vcl/source/bitmap/BitmapSolarizeFilter \ vcl/source/bitmap/BitmapSepiaFilter \ @@ -321,13 +328,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/bitmap/BitmapConvolutionMatrixFilter \ vcl/source/bitmap/BitmapMedianFilter \ vcl/source/bitmap/BitmapInterpolateScaleFilter \ - vcl/source/bitmap/BitmapLightenFilter \ - vcl/source/bitmap/BitmapDisabledImageFilter \ - vcl/source/bitmap/BitmapColorizeFilter \ - vcl/source/bitmap/bitmappaint \ - vcl/source/bitmap/BitmapGaussianSeparableBlurFilter \ vcl/source/bitmap/BitmapSeparableUnsharpenFilter \ - vcl/source/bitmap/BitmapSmoothenFilter \ vcl/source/bitmap/BitmapFastScaleFilter \ vcl/source/bitmap/BitmapScaleSuperFilter \ vcl/source/bitmap/BitmapScaleConvolutionFilter \ diff --git a/vcl/qa/cppunit/BitmapTest.cxx b/vcl/qa/cppunit/BitmapTest.cxx index f835c7b78bc3..706fb1f58690 100644 --- a/vcl/qa/cppunit/BitmapTest.cxx +++ b/vcl/qa/cppunit/BitmapTest.cxx @@ -25,6 +25,7 @@ #if HAVE_FEATURE_OPENGL #include #endif +#include #include #include @@ -211,7 +212,9 @@ void BitmapTest::testMonochrome() { Bitmap aBmp = createTestBitmap(); - aBmp.MakeMonochrome(63); + BitmapEx aBmpEx(aBmp); + BitmapFilter::Filter(aBmpEx, BitmapMonochromeFilter(63)); + aBmp = aBmpEx.GetBitmap(); BitmapReadAccess aBmpReadAccess(aBmp); CPPUNIT_ASSERT_EQUAL_MESSAGE("Black pixel wrong monochrome value", BitmapColor(COL_BLACK), diff --git a/vcl/source/bitmap/BitmapMonochromeFilter.cxx b/vcl/source/bitmap/BitmapMonochromeFilter.cxx new file mode 100644 index 000000000000..0bdb2cd09226 --- /dev/null +++ b/vcl/source/bitmap/BitmapMonochromeFilter.cxx @@ -0,0 +1,101 @@ +/* -*- 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 +#include +#include +#include + +#include + +BitmapEx BitmapMonochromeFilter::execute(BitmapEx const& aBitmapEx) +{ + Bitmap aBitmap = aBitmapEx.GetBitmap(); + Bitmap::ScopedReadAccess pReadAcc(aBitmap); + bool bRet = false; + + if (pReadAcc) + { + Bitmap aNewBmp(aBitmap.GetSizePixel(), 1); + BitmapScopedWriteAccess pWriteAcc(aNewBmp); + + if (pWriteAcc) + { + const BitmapColor aBlack(pWriteAcc->GetBestMatchingColor(COL_BLACK)); + const BitmapColor aWhite(pWriteAcc->GetBestMatchingColor(COL_WHITE)); + const long nWidth = pWriteAcc->Width(); + const long nHeight = pWriteAcc->Height(); + + if (pReadAcc->HasPalette()) + { + for (long nY = 0; nY < nHeight; nY++) + { + Scanline pScanline = pWriteAcc->GetScanline(nY); + Scanline pScanlineRead = pReadAcc->GetScanline(nY); + for (long nX = 0; nX < nWidth; nX++) + { + const sal_uInt8 cIndex = pReadAcc->GetIndexFromData(pScanlineRead, nX); + if (pReadAcc->GetPaletteColor(cIndex).GetLuminance() >= mcThreshold) + { + pWriteAcc->SetPixelOnData(pScanline, nX, aWhite); + } + else + { + pWriteAcc->SetPixelOnData(pScanline, nX, aBlack); + } + } + } + } + else + { + for (long nY = 0; nY < nHeight; nY++) + { + Scanline pScanline = pWriteAcc->GetScanline(nY); + Scanline pScanlineRead = pReadAcc->GetScanline(nY); + for (long nX = 0; nX < nWidth; nX++) + { + if (pReadAcc->GetPixelFromData(pScanlineRead, nX).GetLuminance() + >= mcThreshold) + { + pWriteAcc->SetPixelOnData(pScanline, nX, aWhite); + } + else + { + pWriteAcc->SetPixelOnData(pScanline, nX, aBlack); + } + } + } + } + + pWriteAcc.reset(); + bRet = true; + } + + pReadAcc.reset(); + + if (bRet) + { + const MapMode aMap(aBitmap.GetPrefMapMode()); + const Size aSize(aBitmap.GetPrefSize()); + + aBitmap = aNewBmp; + + aBitmap.SetPrefMapMode(aMap); + aBitmap.SetPrefSize(aSize); + } + } + + if (bRet) + return BitmapEx(aBitmap); + + return BitmapEx(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/bitmap/bitmap.cxx b/vcl/source/bitmap/bitmap.cxx index b273bbfca983..23477b6e60ab 100644 --- a/vcl/source/bitmap/bitmap.cxx +++ b/vcl/source/bitmap/bitmap.cxx @@ -850,82 +850,6 @@ Bitmap Bitmap::CreateDisplayBitmap( OutputDevice* pDisplay ) return aDispBmp; } -bool Bitmap::MakeMonochrome(sal_uInt8 cThreshold) -{ - ScopedReadAccess pReadAcc(*this); - bool bRet = false; - - if( pReadAcc ) - { - Bitmap aNewBmp( GetSizePixel(), 1 ); - BitmapScopedWriteAccess pWriteAcc(aNewBmp); - - if( pWriteAcc ) - { - const BitmapColor aBlack( pWriteAcc->GetBestMatchingColor( COL_BLACK ) ); - const BitmapColor aWhite( pWriteAcc->GetBestMatchingColor( COL_WHITE ) ); - const long nWidth = pWriteAcc->Width(); - const long nHeight = pWriteAcc->Height(); - - if( pReadAcc->HasPalette() ) - { - for( long nY = 0; nY < nHeight; nY++ ) - { - Scanline pScanline = pWriteAcc->GetScanline(nY); - Scanline pScanlineRead = pReadAcc->GetScanline(nY); - for( long nX = 0; nX < nWidth; nX++ ) - { - const sal_uInt8 cIndex = pReadAcc->GetIndexFromData( pScanlineRead, nX ); - if( pReadAcc->GetPaletteColor( cIndex ).GetLuminance() >= - cThreshold ) - { - pWriteAcc->SetPixelOnData( pScanline, nX, aWhite ); - } - else - pWriteAcc->SetPixelOnData( pScanline, nX, aBlack ); - } - } - } - else - { - for( long nY = 0; nY < nHeight; nY++ ) - { - Scanline pScanline = pWriteAcc->GetScanline(nY); - Scanline pScanlineRead = pReadAcc->GetScanline(nY); - for( long nX = 0; nX < nWidth; nX++ ) - { - if( pReadAcc->GetPixelFromData( pScanlineRead, nX ).GetLuminance() >= - cThreshold ) - { - pWriteAcc->SetPixelOnData( pScanline, nX, aWhite ); - } - else - pWriteAcc->SetPixelOnData( pScanline, nX, aBlack ); - } - } - } - - pWriteAcc.reset(); - bRet = true; - } - - pReadAcc.reset(); - - if( bRet ) - { - const MapMode aMap( maPrefMapMode ); - const Size aSize( maPrefSize ); - - *this = aNewBmp; - - maPrefMapMode = aMap; - maPrefSize = aSize; - } - } - - return bRet; -} - bool Bitmap::GetSystemData( BitmapSystemData& rData ) const { bool bRet = false; diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx index 8503db8fc2ca..e178a0c845b3 100644 --- a/vcl/source/gdi/bitmap3.cxx +++ b/vcl/source/gdi/bitmap3.cxx @@ -27,6 +27,7 @@ #if HAVE_FEATURE_OPENGL #include #endif +#include #include #include @@ -245,7 +246,11 @@ bool Bitmap::Convert( BmpConversion eConversion ) switch( eConversion ) { case BmpConversion::N1BitThreshold: - bRet = MakeMonochrome(128); + { + BitmapEx aBmpEx(*this); + bRet = BitmapFilter::Filter(aBmpEx, BitmapMonochromeFilter(128)); + *this = aBmpEx.GetBitmap(); + } break; case BmpConversion::N4BitGreys: diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx index 4d31dbb1fa0a..c81b8b0fd446 100644 --- a/vcl/source/gdi/bitmapex.cxx +++ b/vcl/source/gdi/bitmapex.cxx @@ -34,6 +34,7 @@ #include #include #include +#include // BitmapEx::Create #include @@ -125,7 +126,9 @@ BitmapEx::BitmapEx( const Bitmap& rBmp, const Bitmap& rMask ) : if( !!maMask && maMask.GetBitCount() != 1 ) { SAL_WARN( "vcl", "BitmapEx: forced mask to monochrome"); - maMask.MakeMonochrome(255); + BitmapEx aMaskEx(maMask); + BitmapFilter::Filter(aMaskEx, BitmapMonochromeFilter(255)); + maMask = aMaskEx.GetBitmap(); } if (!!maBitmap && !!maMask && maBitmap.GetSizePixel() != maMask.GetSizePixel()) @@ -249,8 +252,13 @@ Bitmap BitmapEx::GetMask() const { Bitmap aRet( maMask ); - if( IsAlpha() ) - aRet.MakeMonochrome(255); + if (IsAlpha()) + { + + BitmapEx aMaskEx(aRet); + BitmapFilter::Filter(aMaskEx, BitmapMonochromeFilter(255)); + aRet = aMaskEx.GetBitmap(); + } return aRet; } diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx index e924a1f35f58..4108bc6f2cf8 100644 --- a/vcl/source/outdev/bitmap.cxx +++ b/vcl/source/outdev/bitmap.cxx @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -327,9 +328,9 @@ void OutputDevice::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize, // DRAWMODE_BLACK/WHITEBITMAP requires monochrome // output, having alpha-induced grey levels is not // acceptable. - Bitmap aMask( aBmpEx.GetAlpha().GetBitmap() ); - aMask.MakeMonochrome(129); - aBmpEx = BitmapEx( aColorBmp, aMask ); + BitmapEx aMaskEx(aBmpEx.GetAlpha().GetBitmap()); + BitmapFilter::Filter(aMaskEx, BitmapMonochromeFilter(129)); + aBmpEx = BitmapEx(aColorBmp, aMaskEx.GetBitmap()); } else { -- cgit