summaryrefslogtreecommitdiff
path: root/emfio
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2020-09-21 08:43:48 +0200
committerMiklos Vajna <vmiklos@collabora.com>2020-09-21 15:21:49 +0200
commitee2911ad64eb7a84c96e4a0e3e4a1352282129ef (patch)
tree1d58c6b3df5c241b617920ce8a4757ce8704a498 /emfio
parent6fe626727e35b837511851f2e4ea79f61e90586d (diff)
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.hxx4
-rw-r--r--emfio/source/reader/emfreader.cxx82
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);