[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - emfio/inc emfio/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Mon Sep 21 13:22:22 UTC 2020


 emfio/inc/emfreader.hxx           |    4 +
 emfio/source/reader/emfreader.cxx |   82 +++++++++++++++++++++++++++++++++++---
 2 files changed, 80 insertions(+), 6 deletions(-)

New commits:
commit ee2911ad64eb7a84c96e4a0e3e4a1352282129ef
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Sep 21 08:43:48 2020 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon Sep 21 15:21:49 2020 +0200

    tdf#136836 emfio: speed up import of EMF import when the orig PDF is available
    
    The PPTX bugdoc has a 17MB EMF file, which has enough instructions to
    keep Impress busy for minutes during import.
    
    Take advantage of the detail that this EMF has a
    EMR_COMMENT_MULTIFORMATS record that contains the original PDF, which
    can be rendered much faster:
    
    - old cost: 122.153 seconds
    - new cost: 1.952 seconds (1.6% of baseline)
    
    (cherry picked from commit d75c5b38911557173c54a78f42ff220ab3918573)
    
    Change-Id: I38efc1c24e21a7622377b9e1c1938ebee826bae9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103099
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/emfio/inc/emfreader.hxx b/emfio/inc/emfreader.hxx
index 90d8969ae70c..75a77211ea61 100644
--- a/emfio/inc/emfreader.hxx
+++ b/emfio/inc/emfreader.hxx
@@ -32,6 +32,8 @@ namespace emfio
         bool        mbRecordPath : 1;
         bool        mbEMFPlus : 1;
         bool        mbEMFPlusDualMode : 1;
+        /// An other format is read already, can ignore actual EMF data.
+        bool mbReadOtherGraphicFormat = false;
 
         bool        ReadHeader();
         // reads and converts the rectangle
@@ -43,6 +45,8 @@ namespace emfio
 
         bool ReadEnhWMF();
         void ReadGDIComment(sal_uInt32 nCommentId);
+        /// Parses EMR_COMMENT_MULTIFORMATS.
+        void ReadMultiformatsComment();
 
     private:
         template <class T> void ReadAndDrawPolyPolygon(sal_uInt32 nNextPos);
diff --git a/emfio/source/reader/emfreader.cxx b/emfio/source/reader/emfreader.cxx
index 300a4337992f..e59b7eaa5adc 100644
--- a/emfio/source/reader/emfreader.cxx
+++ b/emfio/source/reader/emfreader.cxx
@@ -26,6 +26,8 @@
 #include <o3tl/safeint.hxx>
 #include <tools/stream.hxx>
 #include <memory>
+#include <vcl/graph.hxx>
+#include <vcl/pdfread.hxx>
 
 #ifdef DBG_UTIL
 #include <vcl/pngwrite.hxx>
@@ -165,6 +167,8 @@ using namespace std;
 #define EMR_SETLINKEDUFIS              119
 #define EMR_SETTEXTJUSTIFICATION       120
 
+#define PDF_SIGNATURE 0x50444620 // "PDF "
+
 namespace
 {
 
@@ -383,7 +387,6 @@ namespace emfio
     {
     }
 
-#if OSL_DEBUG_LEVEL > 0
     const sal_uInt32 EMR_COMMENT_BEGINGROUP = 0x00000002;
     const sal_uInt32 EMR_COMMENT_ENDGROUP = 0x00000003;
     const sal_uInt32 EMR_COMMENT_MULTIFORMATS = 0x00000004;
@@ -433,7 +436,7 @@ namespace emfio
                 break;
 
             case EMR_COMMENT_MULTIFORMATS:
-                SAL_WARN("emfio", "\t\tEMR_COMMENT_MULTIFORMATS not implemented");
+                ReadMultiformatsComment();
                 break;
 
             case EMR_COMMENT_WINDOWS_METAFILE:
@@ -445,11 +448,78 @@ namespace emfio
                 break;
         }
     }
-#else
-    void EmfReader::ReadGDIComment(sal_uInt32)
+
+    void EmfReader::ReadMultiformatsComment()
     {
+        tools::Rectangle aOutputRect = EmfReader::ReadRectangle();
+
+        sal_uInt32 nCountFormats;
+        mpInputStream->ReadUInt32(nCountFormats);
+        if (nCountFormats < 1)
+        {
+            return;
+        }
+
+        // Read the first EmrFormat.
+        sal_uInt32 nSignature;
+        mpInputStream->ReadUInt32(nSignature);
+        if (nSignature != PDF_SIGNATURE)
+        {
+            return;
+        }
+
+        sal_uInt32 nVersion;
+        mpInputStream->ReadUInt32(nVersion);
+        if (nVersion != 1)
+        {
+            return;
+        }
+
+        sal_uInt32 nSizeData;
+        mpInputStream->ReadUInt32(nSizeData);
+        if (!nSizeData || nSizeData > mpInputStream->remainingSize())
+        {
+            return;
+        }
+
+        sal_uInt32 nOffData;
+        mpInputStream->ReadUInt32(nOffData);
+        if (!nOffData)
+        {
+            return;
+        }
+
+        std::vector<char> aPdfData(nSizeData);
+        mpInputStream->ReadBytes(aPdfData.data(), aPdfData.size());
+        if (!mpInputStream->good())
+        {
+            return;
+        }
+
+        SvMemoryStream aPdfStream;
+        aPdfStream.WriteBytes(aPdfData.data(), aPdfData.size());
+        aPdfStream.Seek(0);
+        Graphic aGraphic;
+        if (!vcl::ImportPDF(aPdfStream, aGraphic))
+        {
+            return;
+        }
+
+        maBmpSaveList.emplace_back(new BSaveStruct(aGraphic.GetBitmapEx(), aOutputRect, SRCCOPY));
+        const std::shared_ptr<VectorGraphicData> pVectorGraphicData
+            = aGraphic.getVectorGraphicData();
+        if (!pVectorGraphicData)
+        {
+            return;
+        }
+
+        if (pVectorGraphicData->getVectorGraphicDataType() != VectorGraphicDataType::Pdf)
+        {
+            return;
+        }
+
+        mbReadOtherGraphicFormat = true;
     }
-#endif
 
     void EmfReader::ReadEMFPlusComment(sal_uInt32 length, bool& bHaveDC)
     {
@@ -730,7 +800,7 @@ namespace emfio
 
         SAL_INFO("emfio", "EMF_PLUS_DISABLE is " << (bEnableEMFPlus ? "enabled" : "disabled"));
 
-        while( bStatus && mnRecordCount-- && mpInputStream->good())
+        while (bStatus && mnRecordCount-- && mpInputStream->good() && !mbReadOtherGraphicFormat)
         {
             sal_uInt32  nRecType(0), nRecSize(0);
             mpInputStream->ReadUInt32(nRecType).ReadUInt32(nRecSize);


More information about the Libreoffice-commits mailing list