include/vcl/graphicfilter.hxx | 8 +++ vcl/qa/cppunit/GraphicTest.cxx | 55 ++++++++++++++++++++++---- vcl/source/filter/graphicfilter2.cxx | 72 ++++++++++++++++++++--------------- vcl/source/gdi/impgraph.cxx | 19 +++++---- 4 files changed, 109 insertions(+), 45 deletions(-)
New commits: commit cd5e86eba163cab14e1d4149dde4513fbe252340 Author: Luke Deller <l...@deller.id.au> AuthorDate: Thu Oct 31 01:36:22 2019 +1100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Nov 8 09:20:17 2019 +0100 tdf#118036 Fix IsTransparent for unloaded graphics Squashed two commits from master: [348460ec37b1] Fix IsTransparent() for unloaded graphics [d93740559872] Fix use of uninitialised variable Change-Id: I1753c0d11491f1dc518e23da8d7b3842945770cb Reviewed-on: https://gerrit.libreoffice.org/81959 Tested-by: Jenkins Tested-by: Xisco FaulĂ <xiscofa...@libreoffice.org> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/include/vcl/graphicfilter.hxx b/include/vcl/graphicfilter.hxx index 69fbc215ba77..88f6a7417f02 100644 --- a/include/vcl/graphicfilter.hxx +++ b/include/vcl/graphicfilter.hxx @@ -145,6 +145,8 @@ class VCL_DLLPUBLIC GraphicDescriptor final GraphicFileFormat nFormat; bool const bOwnStream; sal_uInt8 mnNumberOfImageComponents; + bool bIsTransparent; + bool bIsAlpha; void ImpConstruct(); @@ -214,6 +216,12 @@ public: /** @return number of color channels */ sal_uInt8 GetNumberOfImageComponents() const { return mnNumberOfImageComponents; } + /** @return whether image supports transparency */ + bool IsTransparent() const { return bIsTransparent; } + + /** @return whether image supports alpha values for translucent colours */ + bool IsAlpha() const { return bIsAlpha; } + /** @return filter number that is needed by the GraphFilter to read this format */ static OUString GetImportFormatShortName( GraphicFileFormat nFormat ); }; diff --git a/vcl/qa/cppunit/GraphicTest.cxx b/vcl/qa/cppunit/GraphicTest.cxx index d094da3ca957..c9593434674b 100644 --- a/vcl/qa/cppunit/GraphicTest.cxx +++ b/vcl/qa/cppunit/GraphicTest.cxx @@ -29,25 +29,40 @@ class GraphicTest : public CppUnit::TestFixture void testUnloadedGraphic(); void testUnloadedGraphicLoading(); void testUnloadedGraphicWmf(); + void testUnloadedGraphicAlpha(); CPPUNIT_TEST_SUITE(GraphicTest); CPPUNIT_TEST(testUnloadedGraphic); CPPUNIT_TEST(testUnloadedGraphicLoading); CPPUNIT_TEST(testUnloadedGraphicWmf); + CPPUNIT_TEST(testUnloadedGraphicAlpha); CPPUNIT_TEST_SUITE_END(); }; -BitmapEx createBitmap() +BitmapEx createBitmap(bool alpha = false) { - Bitmap aBitmap(Size(100, 100), 24); + Bitmap aBitmap(Size(120, 100), 24); aBitmap.Erase(COL_LIGHTRED); - return BitmapEx(aBitmap); + aBitmap.SetPrefSize(Size(6000, 5000)); + aBitmap.SetPrefMapMode(MapMode(MapUnit::Map100thMM)); + + if (alpha) + { + sal_uInt8 uAlphaValue = 0x80; + AlphaMask aAlphaMask(Size(120, 100), &uAlphaValue); + + return BitmapEx(aBitmap, aAlphaMask); + } + else + { + return BitmapEx(aBitmap); + } } -void createBitmapAndExportForType(SvStream& rStream, OUString const& sType) +void createBitmapAndExportForType(SvStream& rStream, OUString const& sType, bool alpha) { - BitmapEx aBitmapEx = createBitmap(); + BitmapEx aBitmapEx = createBitmap(alpha); uno::Sequence<beans::PropertyValue> aFilterData; GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter(); @@ -57,11 +72,11 @@ void createBitmapAndExportForType(SvStream& rStream, OUString const& sType) rStream.Seek(STREAM_SEEK_TO_BEGIN); } -Graphic makeUnloadedGraphic(OUString const& sType) +Graphic makeUnloadedGraphic(OUString const& sType, bool alpha = false) { SvMemoryStream aStream; GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter(); - createBitmapAndExportForType(aStream, sType); + createBitmapAndExportForType(aStream, sType, alpha); return rGraphicFilter.ImportUnloadedGraphic(aStream); } @@ -82,10 +97,15 @@ void GraphicTest::testUnloadedGraphic() // check GetSizePixel doesn't load graphic aGraphic = makeUnloadedGraphic("png"); CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); - CPPUNIT_ASSERT_EQUAL(100L, aGraphic.GetSizePixel().Width()); + CPPUNIT_ASSERT_EQUAL(120L, aGraphic.GetSizePixel().Width()); CPPUNIT_ASSERT_EQUAL(100L, aGraphic.GetSizePixel().Height()); CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); + // check GetPrefSize doesn't load graphic + CPPUNIT_ASSERT_EQUAL(6000L, aGraphic.GetPrefSize().Width()); + CPPUNIT_ASSERT_EQUAL(5000L, aGraphic.GetPrefSize().Height()); + CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); + // check GetSizeBytes loads graphic CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); CPPUNIT_ASSERT(aGraphic.GetSizeBytes() > 0); @@ -102,7 +122,7 @@ void GraphicTest::testUnloadedGraphicLoading() // check available CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); - CPPUNIT_ASSERT_EQUAL(100L, aGraphic.GetSizePixel().Width()); + CPPUNIT_ASSERT_EQUAL(120L, aGraphic.GetSizePixel().Width()); CPPUNIT_ASSERT_EQUAL(100L, aGraphic.GetSizePixel().Height()); CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); CPPUNIT_ASSERT(aGraphic.GetSizeBytes() > 0); @@ -158,6 +178,23 @@ void GraphicTest::testUnloadedGraphicWmf() CPPUNIT_ASSERT_EQUAL(Size(42, 42), aGraphic.GetPrefSize()); } +void GraphicTest::testUnloadedGraphicAlpha() +{ + // make unloaded test graphic with alpha + Graphic aGraphic = makeUnloadedGraphic("png", true); + + CPPUNIT_ASSERT_EQUAL(true, aGraphic.IsAlpha()); + CPPUNIT_ASSERT_EQUAL(true, aGraphic.IsTransparent()); + CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); + + // make unloaded test graphic without alpha + aGraphic = makeUnloadedGraphic("png", false); + + CPPUNIT_ASSERT_EQUAL(false, aGraphic.IsAlpha()); + CPPUNIT_ASSERT_EQUAL(false, aGraphic.IsTransparent()); + CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); +} + } // namespace CPPUNIT_TEST_SUITE_REGISTRATION(GraphicTest); diff --git a/vcl/source/filter/graphicfilter2.cxx b/vcl/source/filter/graphicfilter2.cxx index 8839807aa962..2b0230165e05 100644 --- a/vcl/source/filter/graphicfilter2.cxx +++ b/vcl/source/filter/graphicfilter2.cxx @@ -98,6 +98,8 @@ void GraphicDescriptor::ImpConstruct() nBitsPerPixel = 0; nPlanes = 0; mnNumberOfImageComponents = 0; + bIsTransparent = false; + bIsAlpha = false; } bool GraphicDescriptor::ImpDetectBMP( SvStream& rStm, bool bExtendedInfo ) @@ -547,6 +549,11 @@ bool GraphicDescriptor::ImpDetectPNG( SvStream& rStm, bool bExtendedInfo ) rStm.ReadUChar( cByte ); nBitsPerPixel = cByte; + // Colour type - check whether it supports alpha values + sal_uInt8 cColType = 0; + rStm.ReadUChar( cColType ); + bIsAlpha = bIsTransparent = ( cColType == 4 || cColType == 6 ); + // Planes always 1; // compression always nPlanes = 1; @@ -554,46 +561,53 @@ bool GraphicDescriptor::ImpDetectPNG( SvStream& rStm, bool bExtendedInfo ) sal_uInt32 nLen32 = 0; nTemp32 = 0; - rStm.SeekRel( 8 ); + rStm.SeekRel( 7 ); - // read up to the pHYs-Chunk or the start of the image + // read up to the start of the image rStm.ReadUInt32( nLen32 ); rStm.ReadUInt32( nTemp32 ); - while( ( nTemp32 != 0x70485973 ) && ( nTemp32 != 0x49444154 ) - && rStm.good() ) + while( ( nTemp32 != 0x49444154 ) && rStm.good() ) { - rStm.SeekRel( 4 + nLen32 ); - rStm.ReadUInt32( nLen32 ); - rStm.ReadUInt32( nTemp32 ); - } + if ( nTemp32 == 0x70485973 ) // physical pixel dimensions + { + sal_uLong nXRes; + sal_uLong nYRes; - if (nTemp32 == 0x70485973 && rStm.good()) - { - sal_uLong nXRes; - sal_uLong nYRes; + // horizontal resolution + nTemp32 = 0; + rStm.ReadUInt32( nTemp32 ); + nXRes = nTemp32; - // horizontal resolution - nTemp32 = 0; - rStm.ReadUInt32( nTemp32 ); - nXRes = nTemp32; + // vertical resolution + nTemp32 = 0; + rStm.ReadUInt32( nTemp32 ); + nYRes = nTemp32; - // vertical resolution - nTemp32 = 0; - rStm.ReadUInt32( nTemp32 ); - nYRes = nTemp32; + // unit + cByte = 0; + rStm.ReadUChar( cByte ); - // unit - cByte = 0; - rStm.ReadUChar( cByte ); + if ( cByte ) + { + if ( nXRes ) + aLogSize.setWidth( (aPixSize.Width() * 100000) / nXRes ); - if ( cByte ) - { - if ( nXRes ) - aLogSize.setWidth( (aPixSize.Width() * 100000) / nXRes ); + if ( nYRes ) + aLogSize.setHeight( (aPixSize.Height() * 100000) / nYRes ); + } - if ( nYRes ) - aLogSize.setHeight( (aPixSize.Height() * 100000) / nYRes ); + nLen32 -= 9; + } + else if ( nTemp32 == 0x74524e53 ) // transparency + { + bIsTransparent = true; + bIsAlpha = ( cColType != 0 && cColType != 2 ); } + + // skip forward to next chunk + rStm.SeekRel( 4 + nLen32 ); + rStm.ReadUInt32( nLen32 ); + rStm.ReadUInt32( nTemp32 ); } } } diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index 0a7228268876..e15644c9fdc2 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -535,10 +535,11 @@ void ImpGraphic::ImplSetPrepared(bool bAnimated, Size* pSizeHint) maSwapInfo.maPrefSize = *pSizeHint; maSwapInfo.maPrefMapMode = MapMode(MapUnit::Map100thMM); } - else + + GraphicDescriptor aDescriptor(aMemoryStream, nullptr); + if (aDescriptor.Detect(true)) { - GraphicDescriptor aDescriptor(aMemoryStream, nullptr); - if (aDescriptor.Detect(true)) + if (!pSizeHint) { // If we have logic size, work with that, as later pixel -> logic // conversion will work with the output device DPI, not the graphic @@ -554,14 +555,18 @@ void ImpGraphic::ImplSetPrepared(bool bAnimated, Size* pSizeHint) maSwapInfo.maPrefSize = aDescriptor.GetSizePixel(); maSwapInfo.maPrefMapMode = MapMode(MapUnit::MapPixel); } - - maSwapInfo.maSizePixel = aDescriptor.GetSizePixel(); } + + maSwapInfo.maSizePixel = aDescriptor.GetSizePixel(); + maSwapInfo.mbIsTransparent = aDescriptor.IsTransparent(); + maSwapInfo.mbIsAlpha = aDescriptor.IsAlpha(); + } else { + maSwapInfo.mbIsTransparent = false; + maSwapInfo.mbIsAlpha = false; } + maSwapInfo.mnAnimationLoopCount = 0; maSwapInfo.mbIsEPS = false; - maSwapInfo.mbIsTransparent = false; - maSwapInfo.mbIsAlpha = false; maSwapInfo.mbIsAnimated = bAnimated; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits