include/vcl/BitmapPalette.hxx | 5 ++- include/vcl/bitmap.hxx | 3 +- vcl/opengl/salbmp.cxx | 11 ++++++- vcl/qa/cppunit/bitmaprender/BitmapRenderTest.cxx | 2 - vcl/qa/cppunit/jpeg/JpegWriterTest.cxx | 9 +++--- vcl/quartz/salbmp.cxx | 2 - vcl/skia/salbmp.cxx | 6 ++-- vcl/source/bitmap/bitmap.cxx | 34 ++++++++++++++++++++--- vcl/source/bitmap/salbmp.cxx | 2 - vcl/source/filter/jpeg/JpegWriter.cxx | 2 - vcl/source/gdi/alpha.cxx | 2 - vcl/source/gdi/bitmap3.cxx | 4 +- vcl/source/gdi/dibtools.cxx | 4 +- vcl/source/gdi/pdfwriter_impl.cxx | 2 - 14 files changed, 64 insertions(+), 24 deletions(-)
New commits: commit 29dc1029be6d8d02f4b639b32274a286afd0b1b3 Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Sat Jun 27 14:48:36 2020 +0200 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Tue Jun 30 08:02:45 2020 +0200 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.lu...@collabora.com> 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 ) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits