diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2020-09-21 08:43:48 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2020-09-21 15:21:49 +0200 |
commit | ee2911ad64eb7a84c96e4a0e3e4a1352282129ef (patch) | |
tree | 1d58c6b3df5c241b617920ce8a4757ce8704a498 /emfio | |
parent | emfio: extra logging (diff) | |
download | core-ee2911ad64eb7a84c96e4a0e3e4a1352282129ef.tar.gz core-ee2911ad64eb7a84c96e4a0e3e4a1352282129ef.zip |
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@gmail.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'emfio')
-rw-r--r-- | emfio/inc/emfreader.hxx | 4 | ||||
-rw-r--r-- | emfio/source/reader/emfreader.cxx | 82 |
2 files changed, 80 insertions, 6 deletions
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); |