[Libreoffice-commits] core.git: Branch 'libreoffice-6-3' - include/vcl vcl/qa vcl/source

Luke Deller (via logerrit) logerrit at kemper.freedesktop.org
Fri Nov 8 08:20:59 UTC 2019


 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 <luke at deller.id.au>
AuthorDate: Thu Oct 31 01:36:22 2019 +1100
Commit:     Miklos Vajna <vmiklos at 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Ă­ <xiscofauli at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at 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;
 }
 


More information about the Libreoffice-commits mailing list