Make Bitmap::HasAlpha() more reliable
checking for 32-bit format is not sufficient when there are 32-bit formats which do not have actual alpha data. Change the SalBitmap backend interface to return ScanlineFormat rather than BitCount, to give a more reliable picture. Change-Id: I6dde931a05415a9fbe0e8e696173b58e744b0e0c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190242 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
@@ -142,7 +142,7 @@ public:
|
||||
bool HasGreyPalette8Bit() const;
|
||||
bool HasGreyPaletteAny() const;
|
||||
// does this bitmap have alpha information?
|
||||
inline bool HasAlpha() const { return getPixelFormat() == vcl::PixelFormat::N32_BPP; }
|
||||
bool HasAlpha() const;
|
||||
|
||||
/** return the alpha data, copied into an AlphaMask. Will assert if this Bitmap has no alpha. */
|
||||
AlphaMask CreateAlphaMask() const;
|
||||
|
||||
@@ -223,16 +223,11 @@ Size SvpSalBitmap::GetSize() const
|
||||
return aSize;
|
||||
}
|
||||
|
||||
sal_uInt16 SvpSalBitmap::GetBitCount() const
|
||||
ScanlineFormat SvpSalBitmap::GetScanlineFormat() const
|
||||
{
|
||||
sal_uInt16 nBitCount;
|
||||
|
||||
if (moDIB.has_value())
|
||||
nBitCount = moDIB->mnBitCount;
|
||||
else
|
||||
nBitCount = 0;
|
||||
|
||||
return nBitCount;
|
||||
if (!moDIB.has_value())
|
||||
return ScanlineFormat::NONE;
|
||||
return moDIB->meFormat;
|
||||
}
|
||||
|
||||
BitmapBuffer* SvpSalBitmap::AcquireBuffer(BitmapAccessMode)
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
}
|
||||
SAL_DLLPRIVATE virtual void Destroy() final override;
|
||||
SAL_DLLPRIVATE virtual Size GetSize() const override;
|
||||
SAL_DLLPRIVATE virtual sal_uInt16 GetBitCount() const override;
|
||||
SAL_DLLPRIVATE virtual ScanlineFormat GetScanlineFormat() const override;
|
||||
|
||||
SAL_DLLPRIVATE virtual BitmapBuffer* AcquireBuffer( BitmapAccessMode nMode ) override;
|
||||
SAL_DLLPRIVATE virtual void ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ) override;
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
Size& rSize) override;
|
||||
virtual void Destroy() final override;
|
||||
virtual Size GetSize() const override;
|
||||
virtual sal_uInt16 GetBitCount() const override;
|
||||
virtual ScanlineFormat GetScanlineFormat() const override;
|
||||
|
||||
virtual BitmapBuffer* AcquireBuffer(BitmapAccessMode nMode) override;
|
||||
virtual void ReleaseBuffer(BitmapBuffer* pBuffer, BitmapAccessMode nMode) override;
|
||||
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
void Destroy() override;
|
||||
|
||||
Size GetSize() const override;
|
||||
sal_uInt16 GetBitCount() const override;
|
||||
ScanlineFormat GetScanlineFormat() const override;
|
||||
|
||||
BitmapBuffer *AcquireBuffer( BitmapAccessMode nMode ) override;
|
||||
void ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ) override;
|
||||
|
||||
+2
-1
@@ -71,7 +71,8 @@ public:
|
||||
Size& rSize ) = 0;
|
||||
virtual void Destroy() = 0;
|
||||
virtual Size GetSize() const = 0;
|
||||
virtual sal_uInt16 GetBitCount() const = 0;
|
||||
sal_uInt16 GetBitCount() const;
|
||||
virtual ScanlineFormat GetScanlineFormat() const = 0;
|
||||
|
||||
virtual BitmapBuffer* AcquireBuffer( BitmapAccessMode nMode ) = 0;
|
||||
virtual void ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ) = 0;
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
virtual void Destroy() final override;
|
||||
|
||||
virtual Size GetSize() const override;
|
||||
virtual sal_uInt16 GetBitCount() const override;
|
||||
virtual ScanlineFormat GetScanlineFormat() const override;
|
||||
|
||||
virtual BitmapBuffer* AcquireBuffer(BitmapAccessMode nMode) override;
|
||||
virtual void ReleaseBuffer(BitmapBuffer* pBuffer, BitmapAccessMode nMode) override;
|
||||
|
||||
@@ -81,7 +81,7 @@ public:
|
||||
virtual void Destroy() override;
|
||||
|
||||
virtual Size GetSize() const override { return maSize; }
|
||||
virtual sal_uInt16 GetBitCount() const override { return mnBitCount; }
|
||||
virtual ScanlineFormat GetScanlineFormat() const override;
|
||||
|
||||
virtual BitmapBuffer* AcquireBuffer( BitmapAccessMode nMode ) override;
|
||||
virtual void ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode ) override;
|
||||
|
||||
+24
-12
@@ -96,11 +96,30 @@ Size QtBitmap::GetSize() const
|
||||
return Size();
|
||||
}
|
||||
|
||||
sal_uInt16 QtBitmap::GetBitCount() const
|
||||
ScanlineFormat QtBitmap::GetScanlineFormat() const
|
||||
{
|
||||
if (m_pImage)
|
||||
return getFormatBits(m_pImage->format());
|
||||
return 0;
|
||||
if (!m_pImage)
|
||||
return ScanlineFormat::NONE;
|
||||
auto nBits = getFormatBits(m_pImage->format());
|
||||
switch (nBits)
|
||||
{
|
||||
case 1:
|
||||
return ScanlineFormat::N1BitMsbPal;
|
||||
case 8:
|
||||
return ScanlineFormat::N8BitPal;
|
||||
case 24:
|
||||
return ScanlineFormat::N24BitTcRgb;
|
||||
case 32:
|
||||
{
|
||||
#ifdef OSL_BIGENDIAN
|
||||
return ScanlineFormat::N32BitTcArgb;
|
||||
#else
|
||||
return ScanlineFormat::N32BitTcBgra;
|
||||
#endif
|
||||
}
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
BitmapBuffer* QtBitmap::AcquireBuffer(BitmapAccessMode /*nMode*/)
|
||||
@@ -118,28 +137,21 @@ BitmapBuffer* QtBitmap::AcquireBuffer(BitmapAccessMode /*nMode*/)
|
||||
pBuffer->mpBits = m_pImage->bits();
|
||||
pBuffer->mnScanlineSize = m_pImage->bytesPerLine();
|
||||
pBuffer->meDirection = ScanlineDirection::TopDown;
|
||||
pBuffer->meFormat = GetScanlineFormat();
|
||||
|
||||
switch (pBuffer->mnBitCount)
|
||||
{
|
||||
case 1:
|
||||
pBuffer->meFormat = ScanlineFormat::N1BitMsbPal;
|
||||
pBuffer->maPalette = m_aPalette;
|
||||
break;
|
||||
case 8:
|
||||
pBuffer->meFormat = ScanlineFormat::N8BitPal;
|
||||
pBuffer->maPalette = m_aPalette;
|
||||
break;
|
||||
case 24:
|
||||
pBuffer->meFormat = ScanlineFormat::N24BitTcRgb;
|
||||
pBuffer->maPalette = aEmptyPalette;
|
||||
break;
|
||||
case 32:
|
||||
{
|
||||
#ifdef OSL_BIGENDIAN
|
||||
pBuffer->meFormat = ScanlineFormat::N32BitTcArgb;
|
||||
#else
|
||||
pBuffer->meFormat = ScanlineFormat::N32BitTcBgra;
|
||||
#endif
|
||||
pBuffer->maPalette = aEmptyPalette;
|
||||
break;
|
||||
}
|
||||
|
||||
+14
-18
@@ -320,9 +320,20 @@ Size QuartzSalBitmap::GetSize() const
|
||||
return Size( mnWidth, mnHeight );
|
||||
}
|
||||
|
||||
sal_uInt16 QuartzSalBitmap::GetBitCount() const
|
||||
ScanlineFormat QuartzSalBitmap::GetScanlineFormat() const
|
||||
{
|
||||
return mnBits;
|
||||
switch( mnBits )
|
||||
{
|
||||
case 1:
|
||||
return ScanlineFormat::N1BitMsbPal;
|
||||
case 8:
|
||||
return ScanlineFormat::N8BitPal;
|
||||
case 24:
|
||||
return ScanlineFormat::N24BitTcBgr;
|
||||
case 32:
|
||||
return ScanlineFormat::N32BitTcArgb;
|
||||
default: abort();
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -427,22 +438,7 @@ BitmapBuffer* QuartzSalBitmap::AcquireBuffer( BitmapAccessMode /*nMode*/ )
|
||||
pBuffer->mnScanlineSize = mnBytesPerRow;
|
||||
pBuffer->mpBits = m_pUserBuffer.get();
|
||||
pBuffer->mnBitCount = mnBits;
|
||||
switch( mnBits )
|
||||
{
|
||||
case 1:
|
||||
pBuffer->meFormat = ScanlineFormat::N1BitMsbPal;
|
||||
break;
|
||||
case 8:
|
||||
pBuffer->meFormat = ScanlineFormat::N8BitPal;
|
||||
break;
|
||||
case 24:
|
||||
pBuffer->meFormat = ScanlineFormat::N24BitTcBgr;
|
||||
break;
|
||||
case 32:
|
||||
pBuffer->meFormat = ScanlineFormat::N32BitTcArgb;
|
||||
break;
|
||||
default: assert(false);
|
||||
}
|
||||
pBuffer->meFormat = GetScanlineFormat();
|
||||
|
||||
// some BitmapBuffer users depend on a complete palette
|
||||
if( (mnBits <= 8) && !maPalette )
|
||||
|
||||
+29
-30
@@ -201,7 +201,34 @@ void SkiaSalBitmap::Destroy()
|
||||
|
||||
Size SkiaSalBitmap::GetSize() const { return mSize; }
|
||||
|
||||
sal_uInt16 SkiaSalBitmap::GetBitCount() const { return mBitCount; }
|
||||
ScanlineFormat SkiaSalBitmap::GetScanlineFormat() const
|
||||
{
|
||||
switch (mBitCount)
|
||||
{
|
||||
case 1:
|
||||
return ScanlineFormat::N1BitMsbPal;
|
||||
case 8:
|
||||
return ScanlineFormat::N8BitPal;
|
||||
case 24:
|
||||
// Make the RGB/BGR format match the default Skia 32bpp format, to allow
|
||||
// easy conversion later.
|
||||
return kN32_SkColorTypeIsBGRA ? ScanlineFormat::N24BitTcBgr
|
||||
: ScanlineFormat::N24BitTcRgb;
|
||||
case 32:
|
||||
if (m_bWithoutAlpha)
|
||||
{
|
||||
return kN32_SkColorTypeIsBGRA ? ScanlineFormat::N32BitTcBgrx
|
||||
: ScanlineFormat::N32BitTcRgbx;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kN32_SkColorTypeIsBGRA ? ScanlineFormat::N32BitTcBgra
|
||||
: ScanlineFormat::N32BitTcRgba;
|
||||
}
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
BitmapBuffer* SkiaSalBitmap::AcquireBuffer(BitmapAccessMode nMode)
|
||||
{
|
||||
@@ -282,35 +309,7 @@ BitmapBuffer* SkiaSalBitmap::AcquireBuffer(BitmapAccessMode nMode)
|
||||
mPixelsSize = savedPixelsSize;
|
||||
ComputeScanlineSize();
|
||||
}
|
||||
switch (mBitCount)
|
||||
{
|
||||
case 1:
|
||||
buffer->meFormat = ScanlineFormat::N1BitMsbPal;
|
||||
break;
|
||||
case 8:
|
||||
buffer->meFormat = ScanlineFormat::N8BitPal;
|
||||
break;
|
||||
case 24:
|
||||
// Make the RGB/BGR format match the default Skia 32bpp format, to allow
|
||||
// easy conversion later.
|
||||
buffer->meFormat = kN32_SkColorTypeIsBGRA ? ScanlineFormat::N24BitTcBgr
|
||||
: ScanlineFormat::N24BitTcRgb;
|
||||
break;
|
||||
case 32:
|
||||
if (m_bWithoutAlpha)
|
||||
{
|
||||
buffer->meFormat = kN32_SkColorTypeIsBGRA ? ScanlineFormat::N32BitTcBgrx
|
||||
: ScanlineFormat::N32BitTcRgbx;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer->meFormat = kN32_SkColorTypeIsBGRA ? ScanlineFormat::N32BitTcBgra
|
||||
: ScanlineFormat::N32BitTcRgba;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
buffer->meFormat = GetScanlineFormat();
|
||||
buffer->meDirection = ScanlineDirection::TopDown;
|
||||
// Refcount all read/write accesses, to catch problems with existing accesses while
|
||||
// a bitmap changes, and also to detect when we can free mBuffer if wanted.
|
||||
|
||||
@@ -353,6 +353,22 @@ vcl::PixelFormat Bitmap::getPixelFormat() const
|
||||
return vcl::PixelFormat::INVALID;
|
||||
}
|
||||
|
||||
bool Bitmap::HasAlpha() const
|
||||
{
|
||||
if (!mxSalBmp)
|
||||
return false;
|
||||
switch(mxSalBmp->GetScanlineFormat())
|
||||
{
|
||||
case ScanlineFormat::N32BitTcAbgr:
|
||||
case ScanlineFormat::N32BitTcArgb:
|
||||
case ScanlineFormat::N32BitTcBgra:
|
||||
case ScanlineFormat::N32BitTcRgba:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Bitmap::HasGreyPaletteAny() const
|
||||
{
|
||||
bool bRet = false;
|
||||
|
||||
@@ -85,6 +85,28 @@ void SalBitmap::updateChecksum() const
|
||||
}
|
||||
}
|
||||
|
||||
sal_uInt16 SalBitmap::GetBitCount() const
|
||||
{
|
||||
switch (GetScanlineFormat())
|
||||
{
|
||||
case ScanlineFormat::NONE: return 0;
|
||||
case ScanlineFormat::N1BitMsbPal: return 1;
|
||||
case ScanlineFormat::N8BitPal: return 8;
|
||||
case ScanlineFormat::N24BitTcBgr: return 24;
|
||||
case ScanlineFormat::N24BitTcRgb: return 24;
|
||||
case ScanlineFormat::N32BitTcAbgr:
|
||||
case ScanlineFormat::N32BitTcXbgr:
|
||||
case ScanlineFormat::N32BitTcArgb:
|
||||
case ScanlineFormat::N32BitTcXrgb:
|
||||
case ScanlineFormat::N32BitTcBgra:
|
||||
case ScanlineFormat::N32BitTcBgrx:
|
||||
case ScanlineFormat::N32BitTcRgba:
|
||||
case ScanlineFormat::N32BitTcRgbx:
|
||||
return 32;
|
||||
default: abort();
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
||||
+20
-4
@@ -730,6 +730,25 @@ void* WinSalBitmap::ImplCopyDIB( void* pDIB, sal_Int32 nSize )
|
||||
return pCopy;
|
||||
}
|
||||
|
||||
ScanlineFormat WinSalBitmap::GetScanlineFormat() const
|
||||
{
|
||||
if (!mpDIB)
|
||||
return ScanlineFormat::NONE;
|
||||
|
||||
PBITMAPINFO pBI = static_cast<PBITMAPINFO>(mpDIB);
|
||||
if (!pBI)
|
||||
return ScanlineFormat::NONE;
|
||||
|
||||
PBITMAPINFOHEADER pBIH = &pBI->bmiHeader;
|
||||
if( pBIH->biPlanes != 1 )
|
||||
return ScanlineFormat::NONE;
|
||||
|
||||
return pBIH->biBitCount == 8 ? ScanlineFormat::N8BitPal :
|
||||
pBIH->biBitCount == 24 ? ScanlineFormat::N24BitTcBgr :
|
||||
pBIH->biBitCount == 32 ? ScanlineFormat::N32BitTcBgra :
|
||||
ScanlineFormat::NONE;
|
||||
}
|
||||
|
||||
BitmapBuffer* WinSalBitmap::AcquireBuffer( BitmapAccessMode /*nMode*/ )
|
||||
{
|
||||
if (!mpDIB)
|
||||
@@ -746,10 +765,7 @@ BitmapBuffer* WinSalBitmap::AcquireBuffer( BitmapAccessMode /*nMode*/ )
|
||||
{
|
||||
pBuffer.reset(new BitmapBuffer);
|
||||
|
||||
pBuffer->meFormat = pBIH->biBitCount == 8 ? ScanlineFormat::N8BitPal :
|
||||
pBIH->biBitCount == 24 ? ScanlineFormat::N24BitTcBgr :
|
||||
pBIH->biBitCount == 32 ? ScanlineFormat::N32BitTcBgra :
|
||||
ScanlineFormat::NONE;
|
||||
pBuffer->meFormat = GetScanlineFormat();
|
||||
assert (pBuffer->meFormat != ScanlineFormat::NONE);
|
||||
|
||||
if (pBuffer->meFormat != ScanlineFormat::NONE)
|
||||
|
||||
Reference in New Issue
Block a user