Alpha channel in BitmapColor - change bIndex to alpha

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 <quikee@gmail.com>
This commit is contained in:
Tomaž Vajngerl 2016-06-05 18:58:58 +09:00 committed by Tomaž Vajngerl
parent 2ddc618693
commit 1fefdd6f3b
6 changed files with 76 additions and 66 deletions

View file

@ -69,6 +69,8 @@ public:
typedef vcl::ScopedBitmapAccess< BitmapReadAccess, AlphaMask, &AlphaMask::AcquireReadAccess >
ScopedReadAccess;
using Bitmap::IsEmpty;
private:
friend class BitmapEx;
friend class ::OutputDevice;

View file

@ -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<typename charT, typename traits>
inline std::basic_ostream<charT, traits>& operator <<(std::basic_ostream<charT, traits>& rStream, const BitmapColor& rColor)
{
return rStream << "mcBlueOrIndex: " << static_cast<int>(rColor.GetBlueOrIndex()) << ", mcGreen: "
<< static_cast<int>(rColor.GetGreen()) << ", mcRed: " << static_cast<int>(rColor.GetRed()) << ", mbIndex: " << static_cast<int>(rColor.IsIndex());
<< static_cast<int>(rColor.GetGreen()) << ", mcRed: " << static_cast<int>(rColor.GetRed()) << ", mcAlpha: " << static_cast<int>(rColor.GetAlpha());
}
class Palette;
@ -350,18 +352,18 @@ VCL_DLLPUBLIC std::unique_ptr<BitmapBuffer> 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<sal_uInt32>(mcBlueOrIndex) * 28
+ static_cast<sal_uInt32>(mcGreen) * 151
+ static_cast<sal_uInt32>(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<sal_uInt16>(
abs( static_cast<int>(mcBlueOrIndex) - static_cast<int>(rBitmapColor.mcBlueOrIndex) ) +
abs( static_cast<int>(mcGreen) - static_cast<int>(rBitmapColor.mcGreen) ) +

View file

@ -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<sal_uInt8>(0), aBmpColor.GetRed());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Green wrong", static_cast<sal_uInt8>(0), aBmpColor.GetGreen());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast<sal_uInt8>(0), aBmpColor.GetBlue());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Index wrong", false, aBmpColor.IsIndex());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast<sal_uInt8>(0), aBmpColor.GetAlpha());
}
void BitmapColorTest::colorValueConstructor()
@ -70,7 +70,8 @@ void BitmapColorTest::colorValueConstructor()
CPPUNIT_ASSERT_EQUAL_MESSAGE("Green wrong", static_cast<sal_uInt8>(0),
aBmpColor.GetGreen());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast<sal_uInt8>(0), aBmpColor.GetBlue());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Index wrong", false, aBmpColor.IsIndex());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast<sal_uInt8>(0),
aBmpColor.GetAlpha());
}
{
@ -81,7 +82,8 @@ void BitmapColorTest::colorValueConstructor()
aBmpColor.GetGreen());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast<sal_uInt8>(128),
aBmpColor.GetBlue());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Index wrong", false, aBmpColor.IsIndex());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast<sal_uInt8>(0),
aBmpColor.GetAlpha());
}
{
@ -92,7 +94,8 @@ void BitmapColorTest::colorValueConstructor()
aBmpColor.GetGreen());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast<sal_uInt8>(255),
aBmpColor.GetBlue());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Index wrong", false, aBmpColor.IsIndex());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast<sal_uInt8>(0),
aBmpColor.GetAlpha());
}
}
@ -106,7 +109,8 @@ void BitmapColorTest::colorClassConstructor()
CPPUNIT_ASSERT_EQUAL_MESSAGE("Green wrong", static_cast<sal_uInt8>(0),
aBmpColor.GetGreen());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast<sal_uInt8>(0), aBmpColor.GetBlue());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Index wrong", false, aBmpColor.IsIndex());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast<sal_uInt8>(0),
aBmpColor.GetAlpha());
}
{
@ -118,7 +122,8 @@ void BitmapColorTest::colorClassConstructor()
aBmpColor.GetGreen());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast<sal_uInt8>(127),
aBmpColor.GetBlue());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Index wrong", false, aBmpColor.IsIndex());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast<sal_uInt8>(0),
aBmpColor.GetAlpha());
}
{
@ -130,8 +135,33 @@ void BitmapColorTest::colorClassConstructor()
aBmpColor.GetGreen());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast<sal_uInt8>(255),
aBmpColor.GetBlue());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Index wrong", false, aBmpColor.IsIndex());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast<sal_uInt8>(0),
aBmpColor.GetAlpha());
}
// Transparency / Alpha
{
Color aColor(255, 128, 64, 0);
BitmapColor aBmpColor(aColor);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Red wrong", static_cast<sal_uInt8>(128), aBmpColor.GetRed());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Green wrong", static_cast<sal_uInt8>(64),
aBmpColor.GetGreen());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Blue wrong", static_cast<sal_uInt8>(0), aBmpColor.GetBlue());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Alpha wrong", static_cast<sal_uInt8>(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()

View file

@ -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();
}

View file

@ -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)

View file

@ -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;