From 1fefdd6f3b4165491af433a815e6c82aa5ac8204 Mon Sep 17 00:00:00 2001 From: Tomaž Vajngerl Date: Sun, 5 Jun 2016 18:58:58 +0900 Subject: Alpha channel in BitmapColor - change bIndex to alpha MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want to store the alpha channel in BitmapColor. To achieve this we can repurpose bIndex attribute for alpha. Generally we don't need bIndex at all as we can infer if we use index colors or not from the context (using palette or not) Change-Id: I18fe748beeca59e2869368a1c3c2ee9d2062b41e Reviewed-on: https://gerrit.libreoffice.org/61057 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl --- include/vcl/alpha.hxx | 2 + include/vcl/salbtype.hxx | 67 ++++++++++++++------------------ vcl/qa/cppunit/bitmapcolor.cxx | 48 ++++++++++++++++++----- vcl/source/bitmap/BitmapTools.cxx | 13 +------ vcl/source/gdi/bmpacc2.cxx | 6 +-- vcl/unx/generic/print/genpspgraphics.cxx | 6 +-- 6 files changed, 76 insertions(+), 66 deletions(-) diff --git a/include/vcl/alpha.hxx b/include/vcl/alpha.hxx index b1133b967957..b4ec04de031a 100644 --- a/include/vcl/alpha.hxx +++ b/include/vcl/alpha.hxx @@ -69,6 +69,8 @@ public: typedef vcl::ScopedBitmapAccess< BitmapReadAccess, AlphaMask, &AlphaMask::AcquireReadAccess > ScopedReadAccess; + using Bitmap::IsEmpty; + private: friend class BitmapEx; friend class ::OutputDevice; diff --git a/include/vcl/salbtype.hxx b/include/vcl/salbtype.hxx index b965fa333c08..ac2f283e7172 100644 --- a/include/vcl/salbtype.hxx +++ b/include/vcl/salbtype.hxx @@ -94,20 +94,19 @@ private: sal_uInt8 mcBlueOrIndex; sal_uInt8 mcGreen; sal_uInt8 mcRed; - bool mbIndex; + sal_uInt8 mcAlpha; public: inline BitmapColor(); - constexpr BitmapColor( sal_uInt8 cRed, sal_uInt8 cGreen, sal_uInt8 cBlue ); + constexpr BitmapColor( sal_uInt8 cRed, sal_uInt8 cGreen, sal_uInt8 cBlue, sal_uInt8 cAlpha = 0 ); + inline BitmapColor( const Color& rColor ); explicit inline BitmapColor( sal_uInt8 cIndex ); inline bool operator==( const BitmapColor& rBitmapColor ) const; inline bool operator!=( const BitmapColor& rBitmapColor ) const; - inline bool IsIndex() const; - inline sal_uInt8 GetRed() const; inline void SetRed( sal_uInt8 cRed ); @@ -122,6 +121,9 @@ public: Color GetColor() const; + inline sal_uInt8 GetAlpha() const; + inline void SetAlpha( sal_uInt8 cAlpha ); + inline sal_uInt8 GetBlueOrIndex() const; inline BitmapColor& Invert(); @@ -137,7 +139,7 @@ template inline std::basic_ostream& operator <<(std::basic_ostream& rStream, const BitmapColor& rColor) { return rStream << "mcBlueOrIndex: " << static_cast(rColor.GetBlueOrIndex()) << ", mcGreen: " - << static_cast(rColor.GetGreen()) << ", mcRed: " << static_cast(rColor.GetRed()) << ", mbIndex: " << static_cast(rColor.IsIndex()); + << static_cast(rColor.GetGreen()) << ", mcRed: " << static_cast(rColor.GetRed()) << ", mcAlpha: " << static_cast(rColor.GetAlpha()); } class Palette; @@ -350,18 +352,18 @@ VCL_DLLPUBLIC std::unique_ptr StretchAndConvert( ScanlineFormat nDstBitmapFormat, const BitmapPalette* pDstPal = nullptr, const ColorMask* pDstMask = nullptr ); inline BitmapColor::BitmapColor() : - mcBlueOrIndex ( 0 ), - mcGreen ( 0 ), - mcRed ( 0 ), - mbIndex (false) + mcBlueOrIndex (0), + mcGreen (0), + mcRed (0), + mcAlpha (0) { } -constexpr BitmapColor::BitmapColor( sal_uInt8 cRed, sal_uInt8 cGreen, sal_uInt8 cBlue ) : +constexpr BitmapColor::BitmapColor(sal_uInt8 cRed, sal_uInt8 cGreen, sal_uInt8 cBlue, sal_uInt8 cAlpha) : mcBlueOrIndex ( cBlue ), mcGreen ( cGreen ), mcRed ( cRed ), - mbIndex (false) + mcAlpha ( cAlpha ) { } @@ -369,7 +371,7 @@ inline BitmapColor::BitmapColor( const Color& rColor ) : mcBlueOrIndex ( rColor.GetBlue() ), mcGreen ( rColor.GetGreen() ), mcRed ( rColor.GetRed() ), - mbIndex (false) + mcAlpha ( rColor.GetTransparency() ) { } @@ -377,15 +379,16 @@ inline BitmapColor::BitmapColor( sal_uInt8 cIndex ) : mcBlueOrIndex ( cIndex ), mcGreen ( 0 ), mcRed ( 0 ), - mbIndex (true) + mcAlpha ( 0 ) { } inline bool BitmapColor::operator==( const BitmapColor& rBitmapColor ) const { - return( ( mcBlueOrIndex == rBitmapColor.mcBlueOrIndex ) && - ( mbIndex ? rBitmapColor.mbIndex : - ( mcGreen == rBitmapColor.mcGreen && mcRed == rBitmapColor.mcRed ) ) ); + return mcBlueOrIndex == rBitmapColor.mcBlueOrIndex && + mcGreen == rBitmapColor.mcGreen && + mcRed == rBitmapColor.mcRed && + mcAlpha == rBitmapColor.mcAlpha; } inline bool BitmapColor::operator!=( const BitmapColor& rBitmapColor ) const @@ -393,63 +396,59 @@ inline bool BitmapColor::operator!=( const BitmapColor& rBitmapColor ) const return !( *this == rBitmapColor ); } -inline bool BitmapColor::IsIndex() const -{ - return mbIndex; -} - inline sal_uInt8 BitmapColor::GetRed() const { - assert( !mbIndex && "Pixel represents index into colortable" ); return mcRed; } inline void BitmapColor::SetRed( sal_uInt8 cRed ) { - assert( !mbIndex && "Pixel represents index into colortable" ); mcRed = cRed; } inline sal_uInt8 BitmapColor::GetGreen() const { - assert( !mbIndex && "Pixel represents index into colortable" ); return mcGreen; } inline void BitmapColor::SetGreen( sal_uInt8 cGreen ) { - assert( !mbIndex && "Pixel represents index into colortable" ); mcGreen = cGreen; } inline sal_uInt8 BitmapColor::GetBlue() const { - assert( !mbIndex && "Pixel represents index into colortable" ); return mcBlueOrIndex; } inline void BitmapColor::SetBlue( sal_uInt8 cBlue ) { - assert( !mbIndex && "Pixel represents index into colortable" ); mcBlueOrIndex = cBlue; } inline sal_uInt8 BitmapColor::GetIndex() const { - assert( mbIndex && "Pixel represents color values" ); return mcBlueOrIndex; } inline void BitmapColor::SetIndex( sal_uInt8 cIndex ) { - assert( mbIndex && "Pixel represents color values" ); mcBlueOrIndex = cIndex; } inline Color BitmapColor::GetColor() const { - assert( !mbIndex && "Pixel represents index into colortable" ); - return Color(mcRed, mcGreen, mcBlueOrIndex); + return Color(mcAlpha, mcRed, mcGreen, mcBlueOrIndex); +} + +inline sal_uInt8 BitmapColor::GetAlpha() const +{ + return mcAlpha; +} + +inline void BitmapColor::SetAlpha( sal_uInt8 cAlpha ) +{ + mcAlpha = cAlpha; } inline sal_uInt8 BitmapColor::GetBlueOrIndex() const @@ -460,7 +459,6 @@ inline sal_uInt8 BitmapColor::GetBlueOrIndex() const inline BitmapColor& BitmapColor::Invert() { - assert( !mbIndex && "Pixel represents index into colortable" ); mcBlueOrIndex = ~mcBlueOrIndex; mcGreen = ~mcGreen; mcRed = ~mcRed; @@ -470,7 +468,6 @@ inline BitmapColor& BitmapColor::Invert() inline sal_uInt8 BitmapColor::GetLuminance() const { - assert( !mbIndex && "Pixel represents index into colortable" ); return (static_cast(mcBlueOrIndex) * 28 + static_cast(mcGreen) * 151 + static_cast(mcRed) * 77) >> 8; @@ -479,8 +476,6 @@ inline sal_uInt8 BitmapColor::GetLuminance() const inline BitmapColor& BitmapColor::Merge( const BitmapColor& rBitmapColor, sal_uInt8 cTransparency ) { - assert( !mbIndex && "Pixel represents index into colortable" ); - assert( !rBitmapColor.mbIndex && "Pixel represents index into colortable" ); mcBlueOrIndex = ColorChannelMerge( mcBlueOrIndex, rBitmapColor.mcBlueOrIndex, cTransparency ); mcGreen = ColorChannelMerge( mcGreen, rBitmapColor.mcGreen, cTransparency ); mcRed = ColorChannelMerge( mcRed, rBitmapColor.mcRed, cTransparency ); @@ -491,8 +486,6 @@ inline BitmapColor& BitmapColor::Merge( const BitmapColor& rBitmapColor, sal_uIn inline sal_uInt16 BitmapColor::GetColorError( const BitmapColor& rBitmapColor ) const { - assert( !mbIndex && "Pixel represents index into colortable" ); - assert( !rBitmapColor.mbIndex && "Pixel represents index into colortable" ); return static_cast( abs( static_cast(mcBlueOrIndex) - static_cast(rBitmapColor.mcBlueOrIndex) ) + abs( static_cast(mcGreen) - static_cast(rBitmapColor.mcGreen) ) + diff --git a/vcl/qa/cppunit/bitmapcolor.cxx b/vcl/qa/cppunit/bitmapcolor.cxx index 2953c0d0eab8..c8cae6aef973 100644 --- a/vcl/qa/cppunit/bitmapcolor.cxx +++ b/vcl/qa/cppunit/bitmapcolor.cxx @@ -35,9 +35,8 @@ public: void defaultConstructor(); void colorValueConstructor(); void colorClassConstructor(); - + void getColor(); void setValue(); - void invert(); void getLuminance(); @@ -45,6 +44,7 @@ public: CPPUNIT_TEST(defaultConstructor); CPPUNIT_TEST(colorValueConstructor); CPPUNIT_TEST(colorClassConstructor); + CPPUNIT_TEST(getColor); CPPUNIT_TEST(setValue); CPPUNIT_TEST(invert); CPPUNIT_TEST(getLuminance); @@ -58,7 +58,7 @@ void BitmapColorTest::defaultConstructor() CPPUNIT_ASSERT_EQUAL_MESSAGE("Red wrong", static_cast(0), aBmpColor.GetRed()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Green wrong", static_cast(0), aBmpColor.GetGreen()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast(0), aBmpColor.GetBlue()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Index wrong", false, aBmpColor.IsIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast(0), aBmpColor.GetAlpha()); } void BitmapColorTest::colorValueConstructor() @@ -70,7 +70,8 @@ void BitmapColorTest::colorValueConstructor() CPPUNIT_ASSERT_EQUAL_MESSAGE("Green wrong", static_cast(0), aBmpColor.GetGreen()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast(0), aBmpColor.GetBlue()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Index wrong", false, aBmpColor.IsIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast(0), + aBmpColor.GetAlpha()); } { @@ -81,7 +82,8 @@ void BitmapColorTest::colorValueConstructor() aBmpColor.GetGreen()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast(128), aBmpColor.GetBlue()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Index wrong", false, aBmpColor.IsIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast(0), + aBmpColor.GetAlpha()); } { @@ -92,7 +94,8 @@ void BitmapColorTest::colorValueConstructor() aBmpColor.GetGreen()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast(255), aBmpColor.GetBlue()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Index wrong", false, aBmpColor.IsIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast(0), + aBmpColor.GetAlpha()); } } @@ -106,7 +109,8 @@ void BitmapColorTest::colorClassConstructor() CPPUNIT_ASSERT_EQUAL_MESSAGE("Green wrong", static_cast(0), aBmpColor.GetGreen()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast(0), aBmpColor.GetBlue()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Index wrong", false, aBmpColor.IsIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast(0), + aBmpColor.GetAlpha()); } { @@ -118,7 +122,8 @@ void BitmapColorTest::colorClassConstructor() aBmpColor.GetGreen()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast(127), aBmpColor.GetBlue()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Index wrong", false, aBmpColor.IsIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast(0), + aBmpColor.GetAlpha()); } { @@ -130,10 +135,35 @@ void BitmapColorTest::colorClassConstructor() aBmpColor.GetGreen()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast(255), aBmpColor.GetBlue()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Index wrong", false, aBmpColor.IsIndex()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast(0), + aBmpColor.GetAlpha()); + } + + // Transparency / Alpha + { + Color aColor(255, 128, 64, 0); + BitmapColor aBmpColor(aColor); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("Red wrong", static_cast(128), aBmpColor.GetRed()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Green wrong", static_cast(64), + aBmpColor.GetGreen()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast(0), aBmpColor.GetBlue()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast(255), + aBmpColor.GetAlpha()); } } +void BitmapColorTest::getColor() +{ + BitmapColor aBitmapColor(255, 128, 64, 32); + Color aColor = aBitmapColor.GetColor(); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("Red wrong", sal_uInt8(255), aColor.GetRed()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Green wrong", sal_uInt8(128), aColor.GetGreen()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", sal_uInt8(64), aColor.GetBlue()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Transparecy wrong", sal_uInt8(32), aColor.GetTransparency()); +} + void BitmapColorTest::setValue() { BitmapColor aBmpColor; diff --git a/vcl/source/bitmap/BitmapTools.cxx b/vcl/source/bitmap/BitmapTools.cxx index aaa678b888dd..13a133295b06 100644 --- a/vcl/source/bitmap/BitmapTools.cxx +++ b/vcl/source/bitmap/BitmapTools.cxx @@ -652,18 +652,7 @@ css::uno::Sequence< sal_Int8 > GetMaskDIB(BitmapEx const & aBmpEx) static sal_uInt8 lcl_GetColor(BitmapColor const& rColor) { - sal_uInt8 nTemp(0); - if (rColor.IsIndex()) - { - nTemp = rColor.GetIndex(); - } - else - { - nTemp = rColor.GetBlue(); - // greyscale expected here, or what would non-grey colors mean? - assert(rColor.GetRed() == nTemp && rColor.GetGreen() == nTemp); - } - return nTemp; + return rColor.GetBlueOrIndex(); } diff --git a/vcl/source/gdi/bmpacc2.cxx b/vcl/source/gdi/bmpacc2.cxx index 1d7cec5f4c79..25606c09509e 100644 --- a/vcl/source/gdi/bmpacc2.cxx +++ b/vcl/source/gdi/bmpacc2.cxx @@ -79,11 +79,7 @@ BitmapColor BitmapReadAccess::GetPixelForN8BitPal(ConstScanline pScanline, long void BitmapReadAccess::SetPixelForN8BitPal(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask&) { - if (rBitmapColor.IsIndex()) - pScanline[ nX ] = rBitmapColor.GetIndex(); - else - // Let's hope that the RGB color values equal, so it doesn't matter what do we pick - pScanline[ nX ] = rBitmapColor.GetBlueOrIndex(); + pScanline[ nX ] = rBitmapColor.GetBlueOrIndex(); } BitmapColor BitmapReadAccess::GetPixelForN8BitTcMask(ConstScanline pScanline, long nX, const ColorMask& rMask) diff --git a/vcl/unx/generic/print/genpspgraphics.cxx b/vcl/unx/generic/print/genpspgraphics.cxx index f74ecffdb990..88e7fcdf901a 100644 --- a/vcl/unx/generic/print/genpspgraphics.cxx +++ b/vcl/unx/generic/print/genpspgraphics.cxx @@ -192,7 +192,7 @@ SalPrinterBmp::GetPixelRGB (sal_uInt32 nRow, sal_uInt32 nColumn) const Scanline pScan = mpScanAccess + nRow * mnScanOffset; BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask); - if (aColor.IsIndex()) + if (!!mpBmpBuffer->maPalette) GetPaletteColor(aColor.GetIndex()); return ((aColor.GetBlue()) & 0x000000ff) @@ -206,7 +206,7 @@ SalPrinterBmp::GetPixelGray (sal_uInt32 nRow, sal_uInt32 nColumn) const Scanline pScan = mpScanAccess + nRow * mnScanOffset; BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask); - if (aColor.IsIndex()) + if (!!mpBmpBuffer->maPalette) aColor = mpBmpBuffer->maPalette[aColor.GetIndex()]; return ( aColor.GetBlue() * 28UL @@ -221,7 +221,7 @@ SalPrinterBmp::GetPixelIdx (sal_uInt32 nRow, sal_uInt32 nColumn) const Scanline pScan = mpScanAccess + nRow * mnScanOffset; BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask); - if (aColor.IsIndex()) + if (!!mpBmpBuffer->maPalette) return aColor.GetIndex(); else return 0; -- cgit