summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2020-06-27 14:48:36 +0200
committerLuboš Luňák <l.lunak@collabora.com>2020-06-30 08:02:45 +0200
commit29dc1029be6d8d02f4b639b32274a286afd0b1b3 (patch)
tree0b49af8c7324ed9956f3366d6a09726e52ffc06a
parent63f3485b57904de4e77c04f5759e6563fcce6748 (diff)
differentiate between 8bit and any-bit grey palette (tdf#121120)
Only the grey palette with 256 colors means that pixel values map directly to color values. Tdf#121120 has an image with 2-bit palette where color index 1 is (255,255,255), but that means the pixel value 1 cannot be just treated as color. Change-Id: Ifbd953af7f291e4fb8032ea0f4c33c0514770856 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97283 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
-rw-r--r--include/vcl/BitmapPalette.hxx5
-rw-r--r--include/vcl/bitmap.hxx3
-rw-r--r--vcl/opengl/salbmp.cxx11
-rw-r--r--vcl/qa/cppunit/bitmaprender/BitmapRenderTest.cxx2
-rw-r--r--vcl/qa/cppunit/jpeg/JpegWriterTest.cxx9
-rw-r--r--vcl/quartz/salbmp.cxx2
-rw-r--r--vcl/skia/salbmp.cxx6
-rw-r--r--vcl/source/bitmap/bitmap.cxx34
-rw-r--r--vcl/source/bitmap/salbmp.cxx2
-rw-r--r--vcl/source/filter/jpeg/JpegWriter.cxx2
-rw-r--r--vcl/source/gdi/alpha.cxx2
-rw-r--r--vcl/source/gdi/bitmap3.cxx4
-rw-r--r--vcl/source/gdi/dibtools.cxx4
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx2
14 files changed, 64 insertions, 24 deletions
diff --git a/include/vcl/BitmapPalette.hxx b/include/vcl/BitmapPalette.hxx
index ba6ef09af9f4..9a2d08d4dccb 100644
--- a/include/vcl/BitmapPalette.hxx
+++ b/include/vcl/BitmapPalette.hxx
@@ -128,7 +128,10 @@ public:
return nRetIndex;
}
- bool IsGreyPalette() const;
+ /// Returns true if the palette is 8-bit grey palette.
+ bool IsGreyPalette8Bit() const;
+ /// Returns true if the paleete is a grey palette (may not be 8-bit).
+ bool IsGreyPaletteAny() const;
};
#endif // INCLUDED_VCL_BITMAPPALETTE_HXX
diff --git a/include/vcl/bitmap.hxx b/include/vcl/bitmap.hxx
index 742e7a3a56f8..9ed602942322 100644
--- a/include/vcl/bitmap.hxx
+++ b/include/vcl/bitmap.hxx
@@ -133,7 +133,8 @@ public:
sal_uInt16 GetBitCount() const;
inline sal_Int64 GetColorCount() const;
inline sal_uLong GetSizeBytes() const;
- bool HasGreyPalette() const;
+ bool HasGreyPalette8Bit() const;
+ bool HasGreyPaletteAny() const;
/** get system dependent bitmap data
@param rData
diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx
index cd3a56a7ae00..e9b1bca73665 100644
--- a/vcl/opengl/salbmp.cxx
+++ b/vcl/opengl/salbmp.cxx
@@ -356,6 +356,13 @@ GLuint OpenGLSalBitmap::CreateTexture()
determineTextureFormat(mnBits, nFormat, nType);
}
+ else if( mnBits == 8 && maPalette.IsGreyPalette8Bit() )
+ {
+ // no conversion needed for 8bit grayscale
+ pData = mpUserBuffer.get();
+ nFormat = GL_LUMINANCE;
+ nType = GL_UNSIGNED_BYTE;
+ }
else
{
VCL_GL_INFO( "::CreateTexture - convert from " << mnBits << " to 24 bits" );
@@ -401,7 +408,7 @@ bool OpenGLSalBitmap::ReadTexture()
xContext->state().scissor().disable();
xContext->state().stencil().disable();
- if ((mnBits == 8 && maPalette.IsGreyPalette()) || mnBits == 24 || mnBits == 32)
+ if ((mnBits == 8 && maPalette.IsGreyPalette8Bit()) || mnBits == 24 || mnBits == 32)
{
determineTextureFormat(mnBits, nFormat, nType);
@@ -730,7 +737,7 @@ bool OpenGLSalBitmap::ConvertToGreyscale()
VCL_GL_INFO("::ConvertToGreyscale");
// avoid re-converting to 8bits.
- if ( mnBits == 8 && maPalette == Bitmap::GetGreyPalette(256) )
+ if ( mnBits == 8 && maPalette.IsGreyPalette8Bit())
return true;
OpenGLZone aZone;
diff --git a/vcl/qa/cppunit/bitmaprender/BitmapRenderTest.cxx b/vcl/qa/cppunit/bitmaprender/BitmapRenderTest.cxx
index 71bfc40265b5..73e3baab91a3 100644
--- a/vcl/qa/cppunit/bitmaprender/BitmapRenderTest.cxx
+++ b/vcl/qa/cppunit/bitmaprender/BitmapRenderTest.cxx
@@ -248,7 +248,7 @@ void BitmapRenderTest::testTdf116888()
CPPUNIT_ASSERT(pAccess);
const ScanlineFormat eFormat = pAccess->GetScanlineFormat();
CPPUNIT_ASSERT_EQUAL(ScanlineFormat::N8BitPal, eFormat);
- CPPUNIT_ASSERT(!aBitmap.HasGreyPalette());
+ CPPUNIT_ASSERT(!aBitmap.HasGreyPaletteAny());
// HACK: Some rendering backends change white to #FEFEFE while scaling for some reason.
// That is pretty much white too in practice, so adjust for that.
BitmapColor white(COL_WHITE);
diff --git a/vcl/qa/cppunit/jpeg/JpegWriterTest.cxx b/vcl/qa/cppunit/jpeg/JpegWriterTest.cxx
index fc06256c5f86..b4d9d24603eb 100644
--- a/vcl/qa/cppunit/jpeg/JpegWriterTest.cxx
+++ b/vcl/qa/cppunit/jpeg/JpegWriterTest.cxx
@@ -71,7 +71,7 @@ void JpegWriterTest::testWrite8BitGrayscale()
const ScanlineFormat format = access->GetScanlineFormat();
// Check that it's still 8bit grayscale.
CPPUNIT_ASSERT_EQUAL(ScanlineFormat::N8BitPal, format);
- CPPUNIT_ASSERT(bitmap.HasGreyPalette());
+ CPPUNIT_ASSERT(bitmap.HasGreyPalette8Bit());
// Check that the content is valid.
CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_WHITE), access->GetColor(0, 0));
CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_WHITE), access->GetColor(0, access->Width() - 1));
@@ -87,10 +87,11 @@ void JpegWriterTest::testWrite8BitNonGrayscale()
const ScanlineFormat format = access->GetScanlineFormat();
// Check that it's still 8bit grayscale.
CPPUNIT_ASSERT_EQUAL(ScanlineFormat::N8BitPal, format);
- // The original image has grayscale palette, just with entries in a different order,
- // so do not check for non-grayscale, the roundtrip apparently fixes that. What's important
+ // The original image has grayscale palette, just with entries in a different order.
+ // Do not check for grayscale 8bit, the roundtrip apparently fixes that. What's important
// is the content.
- // CPPUNIT_ASSERT(!bitmap.HasGreyPalette());
+ CPPUNIT_ASSERT(bitmap.HasGreyPaletteAny());
+ // CPPUNIT_ASSERT(bitmap.HasGreyPalette8Bit());
// Check that the content is valid.
CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_WHITE), access->GetColor(0, 0));
CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_WHITE), access->GetColor(0, access->Width() - 1));
diff --git a/vcl/quartz/salbmp.cxx b/vcl/quartz/salbmp.cxx
index 524fad183b8e..43c39e66ca23 100644
--- a/vcl/quartz/salbmp.cxx
+++ b/vcl/quartz/salbmp.cxx
@@ -219,7 +219,7 @@ bool QuartzSalBitmap::CreateContext()
// no conversion needed for truecolor
m_pContextBuffer = m_pUserBuffer;
}
- else if( mnBits == 8 && maPalette.IsGreyPalette() )
+ else if( mnBits == 8 && maPalette.IsGreyPalette8Bit() )
{
// no conversion needed for grayscale
m_pContextBuffer = m_pUserBuffer;
diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx
index 2ac221fdba19..5a426fa6e404 100644
--- a/vcl/skia/salbmp.cxx
+++ b/vcl/skia/salbmp.cxx
@@ -348,7 +348,7 @@ bool SkiaSalBitmap::ConvertToGreyscale()
// Avoid the costly SkImage->buffer->SkImage conversion.
if (!mBuffer && mImage)
{
- if (mBitCount == 8 && mPalette == Bitmap::GetGreyPalette(256))
+ if (mBitCount == 8 && mPalette.IsGreyPalette8Bit())
return true;
sk_sp<SkSurface> surface = SkiaHelper::createSkSurface(mPixelsSize);
SkPaint paint;
@@ -377,7 +377,7 @@ bool SkiaSalBitmap::InterpretAs8Bit()
#ifdef DBG_UTIL
assert(mWriteAccessCount == 0);
#endif
- if (mBitCount == 8 && mPalette == Bitmap::GetGreyPalette(256))
+ if (mBitCount == 8 && mPalette.IsGreyPalette8Bit())
return true;
// This is usually used by AlphaMask, the point is just to treat
// the content as an alpha channel. This is often used
@@ -692,7 +692,7 @@ void SkiaSalBitmap::EnsureBitmapData()
}
}
}
- else if (mBitCount == 8 && mPalette.IsGreyPalette())
+ else if (mBitCount == 8 && mPalette.IsGreyPalette8Bit())
{
for (long y = 0; y < mSize.Height(); ++y)
{
diff --git a/vcl/source/bitmap/bitmap.cxx b/vcl/source/bitmap/bitmap.cxx
index fd37da07e9ef..0dae9d5ace4f 100644
--- a/vcl/source/bitmap/bitmap.cxx
+++ b/vcl/source/bitmap/bitmap.cxx
@@ -208,7 +208,7 @@ const BitmapPalette& Bitmap::GetGreyPalette( int nEntries )
return GetGreyPalette(2);
}
-bool BitmapPalette::IsGreyPalette() const
+bool BitmapPalette::IsGreyPaletteAny() const
{
const int nEntryCount = GetEntryCount();
if( !nEntryCount ) // NOTE: an empty palette means 1:1 mapping
@@ -233,6 +233,21 @@ bool BitmapPalette::IsGreyPalette() const
return bRet;
}
+bool BitmapPalette::IsGreyPalette8Bit() const
+{
+ const int nEntryCount = GetEntryCount();
+ if( !nEntryCount ) // NOTE: an empty palette means 1:1 mapping
+ return true;
+ if( nEntryCount != 256 )
+ return false;
+ for (sal_uInt16 i = 0; i < 256; ++i)
+ {
+ if( maBitmapColor[i] != BitmapColor(i, i, i))
+ return false;
+ }
+ return true;
+}
+
Bitmap& Bitmap::operator=( const Bitmap& rBitmap )
{
if (this == &rBitmap)
@@ -303,7 +318,7 @@ sal_uInt16 Bitmap::GetBitCount() const
return 0;
}
-bool Bitmap::HasGreyPalette() const
+bool Bitmap::HasGreyPaletteAny() const
{
const sal_uInt16 nBitCount = GetBitCount();
bool bRet = nBitCount == 1;
@@ -312,7 +327,20 @@ bool Bitmap::HasGreyPalette() const
if( pIAcc )
{
- bRet = pIAcc->HasPalette() && pIAcc->GetPalette().IsGreyPalette();
+ bRet = pIAcc->HasPalette() && pIAcc->GetPalette().IsGreyPaletteAny();
+ }
+
+ return bRet;
+}
+
+bool Bitmap::HasGreyPalette8Bit() const
+{
+ bool bRet = false;
+ ScopedInfoAccess pIAcc(const_cast<Bitmap&>(*this));
+
+ if( pIAcc )
+ {
+ bRet = pIAcc->HasPalette() && pIAcc->GetPalette().IsGreyPalette8Bit();
}
return bRet;
diff --git a/vcl/source/bitmap/salbmp.cxx b/vcl/source/bitmap/salbmp.cxx
index 7e1b9a347140..f731a5690948 100644
--- a/vcl/source/bitmap/salbmp.cxx
+++ b/vcl/source/bitmap/salbmp.cxx
@@ -150,7 +150,7 @@ std::unique_ptr< sal_uInt8[] > SalBitmap::convertDataBitCount( const sal_uInt8*
static const int bpp[] = { 1, 3, 3, 4, 4 };
std::unique_ptr< sal_uInt8[] > data( new sal_uInt8[width * height * bpp[ static_cast<int>(type) ]] );
- if(type == BitConvert::A8 && bitCount == 8 && palette.IsGreyPalette())
+ if(type == BitConvert::A8 && bitCount == 8 && palette.IsGreyPalette8Bit())
{ // no actual data conversion
for( int y = 0; y < height; ++y )
memcpy( data.get() + y * width, src + y * bytesPerRow, width );
diff --git a/vcl/source/filter/jpeg/JpegWriter.cxx b/vcl/source/filter/jpeg/JpegWriter.cxx
index 82ed4bf98ad9..bc41530047ed 100644
--- a/vcl/source/filter/jpeg/JpegWriter.cxx
+++ b/vcl/source/filter/jpeg/JpegWriter.cxx
@@ -231,7 +231,7 @@ bool JPEGWriter::Write( const Graphic& rGraphic )
*mpExpWasGrey = mbGreys;
if ( mbGreys )
- mbNative = ( mpReadAccess->GetScanlineFormat() == ScanlineFormat::N8BitPal && aGraphicBmp.HasGreyPalette());
+ mbNative = ( mpReadAccess->GetScanlineFormat() == ScanlineFormat::N8BitPal && aGraphicBmp.HasGreyPalette8Bit());
else
mbNative = ( mpReadAccess->GetScanlineFormat() == ScanlineFormat::N24BitTcRgb );
diff --git a/vcl/source/gdi/alpha.cxx b/vcl/source/gdi/alpha.cxx
index bc1d54f36c22..3fa43c8eaa6a 100644
--- a/vcl/source/gdi/alpha.cxx
+++ b/vcl/source/gdi/alpha.cxx
@@ -63,7 +63,7 @@ const Bitmap& AlphaMask::ImplGetBitmap() const
void AlphaMask::ImplSetBitmap( const Bitmap& rBitmap )
{
SAL_WARN_IF( 8 != rBitmap.GetBitCount(), "vcl.gdi", "Bitmap should be 8bpp, not " << rBitmap.GetBitCount() << "bpp" );
- SAL_WARN_IF( !rBitmap.HasGreyPalette(), "vcl.gdi", "Bitmap isn't greyscale" );
+ SAL_WARN_IF( !rBitmap.HasGreyPalette8Bit(), "vcl.gdi", "Bitmap isn't greyscale" );
*static_cast<Bitmap*>(this) = rBitmap;
}
diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx
index c9942fc04f76..ec80b03c6008 100644
--- a/vcl/source/gdi/bitmap3.cxx
+++ b/vcl/source/gdi/bitmap3.cxx
@@ -805,7 +805,7 @@ void Bitmap::AdaptBitCount(Bitmap& rNew) const
}
case 4:
{
- if(HasGreyPalette())
+ if(HasGreyPaletteAny())
{
rNew.Convert(BmpConversion::N4BitGreys);
}
@@ -817,7 +817,7 @@ void Bitmap::AdaptBitCount(Bitmap& rNew) const
}
case 8:
{
- if(HasGreyPalette())
+ if(HasGreyPaletteAny())
{
rNew.Convert(BmpConversion::N8BitGreys);
}
diff --git a/vcl/source/gdi/dibtools.cxx b/vcl/source/gdi/dibtools.cxx
index 54d17c83d47c..f2164b94d129 100644
--- a/vcl/source/gdi/dibtools.cxx
+++ b/vcl/source/gdi/dibtools.cxx
@@ -1001,7 +1001,7 @@ bool ImplReadDIBBody(SvStream& rIStm, Bitmap& rBmp, AlphaMask* pBmpAlpha, sal_uL
const BitmapPalette* pPal = &aPalette;
//ofz#948 match the surrounding logic of case TransparentType::Bitmap of
//ReadDIBBitmapEx but do it while reading for performance
- const bool bIsAlpha = (nBitCount == 8 && !!aPalette && aPalette.IsGreyPalette());
+ const bool bIsAlpha = (nBitCount == 8 && !!aPalette && aPalette.IsGreyPalette8Bit());
const bool bForceToMonoWhileReading = (bIsMask && !bIsAlpha && nBitCount != 1);
if (bForceToMonoWhileReading)
{
@@ -1782,7 +1782,7 @@ bool ReadDIBBitmapEx(
if(!!aMask)
{
// do we have an alpha mask?
- if((8 == aMask.GetBitCount()) && aMask.HasGreyPalette())
+ if((8 == aMask.GetBitCount()) && aMask.HasGreyPalette8Bit())
{
AlphaMask aAlpha;
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index de1cea050f04..e68642aa5100 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -8788,7 +8788,7 @@ bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask )
aLine.append( "/ColorSpace" );
if( bTrueColor )
aLine.append( "/DeviceRGB\n" );
- else if( aBitmap.HasGreyPalette() )
+ else if( aBitmap.HasGreyPaletteAny() )
{
aLine.append( "/DeviceGray\n" );
if( aBitmap.GetBitCount() == 1 )