diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2020-06-27 14:48:36 +0200 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2020-07-02 12:58:49 +0200 |
commit | 08278332e3b39fc968a6a7ef603f39cbca108d4e (patch) | |
tree | 435f290fec333e1309c1e1dc0cf0223c0adceb5a /vcl | |
parent | 6089e8b178cf836df3f4cdb0be57376d31a0db76 (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>
(cherry picked from commit 028ae8f61165a95de89993631f96a297c9c1ff94)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97490
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/opengl/salbmp.cxx | 11 | ||||
-rw-r--r-- | vcl/qa/cppunit/bitmaprender/BitmapRenderTest.cxx | 2 | ||||
-rw-r--r-- | vcl/qa/cppunit/jpeg/JpegWriterTest.cxx | 9 | ||||
-rw-r--r-- | vcl/quartz/salbmp.cxx | 2 | ||||
-rw-r--r-- | vcl/skia/salbmp.cxx | 6 | ||||
-rw-r--r-- | vcl/source/bitmap/bitmap.cxx | 34 | ||||
-rw-r--r-- | vcl/source/bitmap/salbmp.cxx | 2 | ||||
-rw-r--r-- | vcl/source/filter/jpeg/JpegWriter.cxx | 2 | ||||
-rw-r--r-- | vcl/source/gdi/alpha.cxx | 2 | ||||
-rw-r--r-- | vcl/source/gdi/bitmap3.cxx | 4 | ||||
-rw-r--r-- | vcl/source/gdi/dibtools.cxx | 4 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 2 |
12 files changed, 58 insertions, 22 deletions
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 2f6820b2877e..8dd09d1765a3 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 22586af61606..439baca41b6f 100644 --- a/vcl/skia/salbmp.cxx +++ b/vcl/skia/salbmp.cxx @@ -351,7 +351,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; @@ -380,7 +380,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 @@ -695,7 +695,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 20045fc78f5e..af5a6f440c7c 100644 --- a/vcl/source/bitmap/bitmap.cxx +++ b/vcl/source/bitmap/bitmap.cxx @@ -178,7 +178,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 @@ -203,6 +203,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) @@ -273,7 +288,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; @@ -282,7 +297,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 a09a5fcf5599..03553d7aa6ee 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -8984,7 +8984,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 ) |