oox/source/helper/graphichelper.cxx                |   15 +++++++++++----
 sw/qa/extras/ooxmlimport/data/image-lazy-read.docx |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx           |    8 ++++++++
 vcl/source/filter/graphicfilter2.cxx               |    9 ++++++++-
 vcl/source/gdi/impgraph.cxx                        |   16 ++++++++++++++--
 vcl/source/graphic/UnoGraphicProvider.cxx          |   19 +++++++++++++++++--
 6 files changed, 58 insertions(+), 9 deletions(-)

New commits:
commit edda1e5fc8113aa4744e32f97c96a3cc311485ca
Author: Miklos Vajna <vmik...@collabora.co.uk>
Date:   Fri Apr 20 16:32:00 2018 +0200

    DOCX import: lazy-read images without external headers
    
    So that similar to ODT, images are not loaded on file open, only when
    the user scrolls there.
    
    Notes:
    
    1) GraphicDescriptor::ImpDetectJPG() would try to calculate the logic
    size before the pixel size is available, so the logic size would be 0x0.
    Also, ImpGraphic::ImplSetPrepared() would always work with a pixel map
    mode. Any of these two would result in a failure of
    testDMLShapeFillBitmapCrop in CppunitTest_sw_ooxmlexport6.
    
    2) Lazy-loading seems to (at the moment) not recognize EMF files, so
    don't lazy-load in case an external header is provided. This probably
    has to be revisited, since the ODF import doesn't go via
    GraphicProvider::queryGraphic().
    
    Change-Id: I44754e659effebca8339715df114dbaadb9b5e9f
    Reviewed-on: https://gerrit.libreoffice.org/53215
    Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk>
    Tested-by: Jenkins <c...@libreoffice.org>

diff --git a/oox/source/helper/graphichelper.cxx 
b/oox/source/helper/graphichelper.cxx
index 7f4262de787c..002d54b946b5 100644
--- a/oox/source/helper/graphichelper.cxx
+++ b/oox/source/helper/graphichelper.cxx
@@ -238,11 +238,13 @@ Reference< XGraphic > GraphicHelper::importGraphic( const 
Reference< XInputStrea
     Reference< XGraphic > xGraphic;
     if( rxInStrm.is() && mxGraphicProvider.is() ) try
     {
-        Sequence< PropertyValue > aArgs( 1 );
+        Sequence< PropertyValue > aArgs( 2 );
         aArgs[ 0 ].Name = "InputStream";
         aArgs[ 0 ].Value <<= rxInStrm;
+        aArgs[ 1 ].Name = "LazyRead";
+        aArgs[ 1 ].Value <<= true;
 
-        if ( pExtHeader && pExtHeader->mapMode > 0 )
+        if ( pExtHeader )
         {
             aArgs.realloc( aArgs.getLength() + 1 );
             Sequence< PropertyValue > aFilterData( 3 );
@@ -252,8 +254,8 @@ Reference< XGraphic > GraphicHelper::importGraphic( const 
Reference< XInputStrea
             aFilterData[ 1 ].Value <<= pExtHeader->yExt;
             aFilterData[ 2 ].Name = "ExternalMapMode";
             aFilterData[ 2 ].Value <<= pExtHeader->mapMode;
-            aArgs[ 1 ].Name = "FilterData";
-            aArgs[ 1 ].Value <<= aFilterData;
+            aArgs[ 2 ].Name = "FilterData";
+            aArgs[ 2 ].Value <<= aFilterData;
         }
 
         xGraphic = mxGraphicProvider->queryGraphic( aArgs );
@@ -339,6 +341,11 @@ Reference< XGraphic > 
GraphicHelper::importEmbeddedGraphic( const OUString& rStr
         EmbeddedGraphicMap::const_iterator aIt = maEmbeddedGraphics.find( 
rStreamName );
         if( aIt == maEmbeddedGraphics.end() )
         {
+            // TODO make lazy-load work for EMF as well.
+            WmfExternal aHeader;
+            if (rStreamName.endsWith(".emf") && !pExtHeader)
+                pExtHeader = &aHeader;
+
             xGraphic = importGraphic(mxStorage->openInputStream(rStreamName), 
pExtHeader);
             if( xGraphic.is() )
                 maEmbeddedGraphics[ rStreamName ] = xGraphic;
diff --git a/sw/qa/extras/ooxmlimport/data/image-lazy-read.docx 
b/sw/qa/extras/ooxmlimport/data/image-lazy-read.docx
new file mode 100644
index 000000000000..faf80e41dcd6
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/image-lazy-read.docx 
differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx 
b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 439658a63b39..7b60b191df67 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -1422,6 +1422,14 @@ DECLARE_OOXMLIMPORT_TEST(testTdf108714, "tdf108714.docx")
     CPPUNIT_ASSERT_EQUAL(style::BreakType_PAGE_BEFORE, breakType);
 }
 
+DECLARE_OOXMLIMPORT_TEST(testImageLazyRead, "image-lazy-read.docx")
+{
+    auto xGraphic = 
getProperty<uno::Reference<graphic::XGraphic>>(getShape(1), "Graphic");
+    Graphic aGraphic(xGraphic);
+    // This failed, import loaded the graphic, it wasn't lazy-read.
+    CPPUNIT_ASSERT(!aGraphic.isAvailable());
+}
+
 DECLARE_OOXMLIMPORT_TEST(testTdf108995, "xml_space.docx")
 {
     CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
diff --git a/vcl/source/filter/graphicfilter2.cxx 
b/vcl/source/filter/graphicfilter2.cxx
index f35ac1c37c81..4439c2ab8b50 100644
--- a/vcl/source/filter/graphicfilter2.cxx
+++ b/vcl/source/filter/graphicfilter2.cxx
@@ -262,6 +262,7 @@ bool GraphicDescriptor::ImpDetectJPG( SvStream& rStm,  bool 
bExtendedInfo )
 
             bool bScanFailure = false;
             bool bScanFinished = false;
+            MapMode aMap;
 
             while (!bScanFailure && !bScanFinished && rStm.good())
             {
@@ -331,7 +332,6 @@ bool GraphicDescriptor::ImpDetectJPG( SvStream& rStm,  bool 
bExtendedInfo )
                                             // setting the logical size
                                             if ( nUnits && 
nHorizontalResolution && nVerticalResolution )
                                             {
-                                                MapMode aMap;
                                                 aMap.SetMapUnit( nUnits == 1 ? 
MapUnit::MapInch : MapUnit::MapCM );
                                                 aMap.SetScaleX( Fraction( 1, 
nHorizontalResolution ) );
                                                 aMap.SetScaleY( Fraction( 1, 
nVerticalResolution ) );
@@ -380,6 +380,13 @@ bool GraphicDescriptor::ImpDetectJPG( SvStream& rStm,  
bool bExtendedInfo )
                                     nBitsPerPixel = ( nNumberOfImageComponents 
== 3 ? 24 : nNumberOfImageComponents == 1 ? 8 : 0 );
                                     nPlanes = 1;
 
+                                    if (aMap.GetMapUnit() != MapUnit::MapPixel)
+                                        // We already know the DPI, but the
+                                        // pixel size arrived later, so do the
+                                        // conversion again.
+                                        aLogSize = OutputDevice::LogicToLogic(
+                                            aPixSize, aMap, 
MapMode(MapUnit::Map100thMM));
+
                                     bScanFinished = true;
                                 }
                                 break;
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
index 9cd9bbb11717..1a9cca6ce0da 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -523,8 +523,20 @@ void ImpGraphic::ImplSetPrepared()
     GraphicDescriptor aDescriptor(aMemoryStream, nullptr);
     if (aDescriptor.Detect(true))
     {
-        maSwapInfo.maPrefSize = aDescriptor.GetSizePixel();
-        maSwapInfo.maPrefMapMode = MapMode(MapUnit::MapPixel);
+        // If we have logic size, work with that, as later pixel -> logic
+        // conversion will work with the output device DPI, not the graphic
+        // DPI.
+        Size aLogSize = aDescriptor.GetSize_100TH_MM();
+        if (aLogSize.getWidth() && aLogSize.getHeight())
+        {
+            maSwapInfo.maPrefSize = aLogSize;
+            maSwapInfo.maPrefMapMode = MapMode(MapUnit::Map100thMM);
+        }
+        else
+        {
+            maSwapInfo.maPrefSize = aDescriptor.GetSizePixel();
+            maSwapInfo.maPrefMapMode = MapMode(MapUnit::MapPixel);
+        }
     }
     maSwapInfo.mnAnimationLoopCount = 0;
     maSwapInfo.mbIsAnimated = false;
diff --git a/vcl/source/graphic/UnoGraphicProvider.cxx 
b/vcl/source/graphic/UnoGraphicProvider.cxx
index 50c273006b85..8b9ccb93bf94 100644
--- a/vcl/source/graphic/UnoGraphicProvider.cxx
+++ b/vcl/source/graphic/UnoGraphicProvider.cxx
@@ -304,6 +304,7 @@ uno::Reference< ::graphic::XGraphic > SAL_CALL 
GraphicProvider::queryGraphic( co
 
     uno::Sequence< ::beans::PropertyValue > aFilterData;
 
+    bool bLazyRead = false;
     for( sal_Int32 i = 0; ( i < rMediaProperties.getLength() ) && !pIStm && 
!xRet.is(); ++i )
     {
         const OUString   aName( rMediaProperties[ i ].Name );
@@ -327,6 +328,8 @@ uno::Reference< ::graphic::XGraphic > SAL_CALL 
GraphicProvider::queryGraphic( co
         {
             aValue >>= aFilterData;
         }
+        else if (aName == "LazyRead")
+            aValue >>= bLazyRead;
     }
 
     // Check for the goal width and height if they are defined
@@ -352,6 +355,9 @@ uno::Reference< ::graphic::XGraphic > SAL_CALL 
GraphicProvider::queryGraphic( co
         }
     }
 
+    if (bLazyRead && aFilterData.hasElements())
+        bLazyRead = false;
+
     SolarMutexGuard g;
 
     if( xIStm.is() )
@@ -392,8 +398,17 @@ uno::Reference< ::graphic::XGraphic > SAL_CALL 
GraphicProvider::queryGraphic( co
             if ( nExtMapMode > 0 )
                 pExtHeader = &aExtHeader;
 
-            ErrCode error = rFilter.ImportGraphic( aVCLGraphic, aPath, *pIStm,
-                GRFILTER_FORMAT_DONTKNOW, nullptr, 
GraphicFilterImportFlags::NONE, pExtHeader );
+            ErrCode error = ERRCODE_NONE;
+            if (bLazyRead)
+            {
+                Graphic aGraphic = rFilter.ImportUnloadedGraphic(*pIStm);
+                if (aGraphic)
+                    aVCLGraphic = aGraphic;
+            }
+            if (!aVCLGraphic)
+                error = rFilter.ImportGraphic(aVCLGraphic, aPath, *pIStm, 
GRFILTER_FORMAT_DONTKNOW,
+                                              nullptr, 
GraphicFilterImportFlags::NONE, pExtHeader);
+
             if( (error == ERRCODE_NONE ) &&
                 ( aVCLGraphic.GetType() != GraphicType::NONE ) )
             {
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to