diff options
author | Chris Sherlock <chris.sherlock79@gmail.com> | 2018-04-19 20:48:29 +1000 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2018-04-22 05:32:45 +0200 |
commit | bcbf767bcfc024e2be839e0c0886f942dd068e4f (patch) | |
tree | e9269a687bae7ba02534caa934573bf6f90c0c4a /vcl | |
parent | 0474be6d5527baab609b16846d6cb38ed89d47fc (diff) |
vcl: ImplPopArt() -> BitmapPopArtFilter
Change-Id: I7b81d0441b5ffdc322a19ca1fea7c7ca63e9e499
Reviewed-on: https://gerrit.libreoffice.org/53151
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/BitmapPopArtFilter.cxx | 118 | ||||
-rw-r--r-- | vcl/source/gdi/bitmap4.cxx | 92 |
3 files changed, 125 insertions, 86 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 72aa7e122217..c39ea5f6b28d 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -313,6 +313,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/bitmap/bitmap \ vcl/source/bitmap/bitmapfilter \ vcl/source/bitmap/BitmapSobelGreyFilter \ + vcl/source/bitmap/BitmapPopArtFilter \ vcl/source/bitmap/BitmapConvolutionMatrixFilter \ vcl/source/bitmap/BitmapMedianFilter \ vcl/source/bitmap/BitmapInterpolateScaleFilter \ diff --git a/vcl/source/bitmap/BitmapPopArtFilter.cxx b/vcl/source/bitmap/BitmapPopArtFilter.cxx new file mode 100644 index 000000000000..15b1b9ea09dd --- /dev/null +++ b/vcl/source/bitmap/BitmapPopArtFilter.cxx @@ -0,0 +1,118 @@ +/* -*- 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/BitmapPopArtFilter.hxx> + +#include <bitmapwriteaccess.hxx> + +#include <cstdlib> + +BitmapEx BitmapPopArtFilter::execute(BitmapEx const& rBitmapEx) +{ + Bitmap aBitmap(rBitmapEx.GetBitmap()); + + bool bRet = (aBitmap.GetBitCount() <= 8) || aBitmap.Convert(BmpConversion::N8BitColors); + + if (bRet) + { + bRet = false; + + BitmapScopedWriteAccess pWriteAcc(aBitmap); + + if (pWriteAcc) + { + const long nWidth = pWriteAcc->Width(); + const long nHeight = pWriteAcc->Height(); + const int nEntryCount = 1 << pWriteAcc->GetBitCount(); + int n = 0; + PopArtEntry* pPopArtTable = new PopArtEntry[nEntryCount]; + + for (n = 0; n < nEntryCount; n++) + { + PopArtEntry& rEntry = pPopArtTable[n]; + rEntry.mnIndex = static_cast<sal_uInt16>(n); + rEntry.mnCount = 0; + } + + // get pixel count for each palette entry + for (long nY = 0; nY < nHeight; nY++) + { + Scanline pScanline = pWriteAcc->GetScanline(nY); + for (long nX = 0; nX < nWidth; nX++) + { + pPopArtTable[pWriteAcc->GetIndexFromData(pScanline, nX)].mnCount++; + } + } + + // sort table + std::qsort(pPopArtTable, nEntryCount, sizeof(PopArtEntry), + [](const void* p1, const void* p2) { + int nRet; + + if (static_cast<PopArtEntry const*>(p1)->mnCount + < static_cast<PopArtEntry const*>(p2)->mnCount) + { + nRet = 1; + } + else if (static_cast<PopArtEntry const*>(p1)->mnCount + == static_cast<PopArtEntry const*>(p2)->mnCount) + { + nRet = 0; + } + else + { + nRet = -1; + } + + return nRet; + }); + + // get last used entry + sal_uLong nFirstEntry; + sal_uLong nLastEntry = 0; + + for (n = 0; n < nEntryCount; n++) + { + if (pPopArtTable[n].mnCount) + nLastEntry = n; + } + + // rotate palette (one entry) + const BitmapColor aFirstCol(pWriteAcc->GetPaletteColor( + sal::static_int_cast<sal_uInt16>(pPopArtTable[0].mnIndex))); + + for (nFirstEntry = 0; nFirstEntry < nLastEntry; nFirstEntry++) + { + pWriteAcc->SetPaletteColor( + sal::static_int_cast<sal_uInt16>(pPopArtTable[nFirstEntry].mnIndex), + pWriteAcc->GetPaletteColor( + sal::static_int_cast<sal_uInt16>(pPopArtTable[nFirstEntry + 1].mnIndex))); + } + + pWriteAcc->SetPaletteColor( + sal::static_int_cast<sal_uInt16>(pPopArtTable[nLastEntry].mnIndex), aFirstCol); + + // cleanup + delete[] pPopArtTable; + pWriteAcc.reset(); + bRet = true; + } + } + + if (bRet) + return BitmapEx(aBitmap); + + return BitmapEx(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/gdi/bitmap4.cxx b/vcl/source/gdi/bitmap4.cxx index edd420b1ea70..656ab4317f99 100644 --- a/vcl/source/gdi/bitmap4.cxx +++ b/vcl/source/gdi/bitmap4.cxx @@ -24,6 +24,7 @@ #include <vcl/BitmapSharpenFilter.hxx> #include <vcl/BitmapMedianFilter.hxx> #include <vcl/BitmapSobelGreyFilter.hxx> +#include <vcl/BitmapPopArtFilter.hxx> #include <bitmapwriteaccess.hxx> @@ -93,7 +94,11 @@ bool Bitmap::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam ) break; case BmpFilter::PopArt: - bRet = ImplPopArt(); + { + BitmapEx aBmpEx(*this); + bRet = BitmapFilter::Filter(aBmpEx, BitmapPopArtFilter()); + *this = aBmpEx.GetBitmap(); + } break; case BmpFilter::DuoTone: @@ -527,91 +532,6 @@ bool Bitmap::ImplMosaic( const BmpFilterParam* pFilterParam ) return bRet; } - -struct PopArtEntry -{ - sal_uInt32 mnIndex; - sal_uInt32 mnCount; -}; - -extern "C" int ImplPopArtCmpFnc( const void* p1, const void* p2 ) -{ - int nRet; - - if( static_cast<PopArtEntry const *>(p1)->mnCount < static_cast<PopArtEntry const *>(p2)->mnCount ) - nRet = 1; - else if( static_cast<PopArtEntry const *>(p1)->mnCount == static_cast<PopArtEntry const *>(p2)->mnCount ) - nRet = 0; - else - nRet = -1; - - return nRet; -} - -bool Bitmap::ImplPopArt() -{ - /* note: GetBitCount() after that is no more than 8 */ - bool bRet = ( GetBitCount() <= 8 ) || Convert( BmpConversion::N8BitColors ); - - if( bRet ) - { - bRet = false; - - BitmapScopedWriteAccess pWriteAcc(*this); - - if( pWriteAcc ) - { - const long nWidth = pWriteAcc->Width(); - const long nHeight = pWriteAcc->Height(); - const int nEntryCount = 1 << pWriteAcc->GetBitCount(); - int n; - PopArtEntry* pPopArtTable = new PopArtEntry[ nEntryCount ]; - - for( n = 0; n < nEntryCount; n++ ) - { - PopArtEntry& rEntry = pPopArtTable[ n ]; - rEntry.mnIndex = static_cast<sal_uInt16>(n); - rEntry.mnCount = 0; - } - - // get pixel count for each palette entry - for( long nY = 0; nY < nHeight ; nY++ ) - { - Scanline pScanline = pWriteAcc->GetScanline(nY); - for( long nX = 0; nX < nWidth; nX++ ) - pPopArtTable[ pWriteAcc->GetIndexFromData( pScanline, nX ) ].mnCount++; - } - - // sort table - qsort( pPopArtTable, nEntryCount, sizeof( PopArtEntry ), ImplPopArtCmpFnc ); - - // get last used entry - sal_uLong nFirstEntry; - sal_uLong nLastEntry = 0; - - for( n = 0; n < nEntryCount; n++ ) - if( pPopArtTable[ n ].mnCount ) - nLastEntry = n; - - // rotate palette (one entry) - const BitmapColor aFirstCol( pWriteAcc->GetPaletteColor( sal::static_int_cast<sal_uInt16>(pPopArtTable[ 0 ].mnIndex) ) ); - for( nFirstEntry = 0; nFirstEntry < nLastEntry; nFirstEntry++ ) - { - pWriteAcc->SetPaletteColor( sal::static_int_cast<sal_uInt16>(pPopArtTable[ nFirstEntry ].mnIndex), - pWriteAcc->GetPaletteColor( sal::static_int_cast<sal_uInt16>(pPopArtTable[ nFirstEntry + 1 ].mnIndex) ) ); - } - pWriteAcc->SetPaletteColor( sal::static_int_cast<sal_uInt16>(pPopArtTable[ nLastEntry ].mnIndex), aFirstCol ); - - // cleanup - delete[] pPopArtTable; - pWriteAcc.reset(); - bRet = true; - } - } - - return bRet; -} - bool Bitmap::ImplDuotoneFilter( const sal_uLong nColorOne, const sal_uLong nColorTwo ) { const long nWidth = GetSizePixel().Width(); |