filter/source/msfilter/escherex.cxx          |    4 
 vcl/inc/graphic/GraphicFormatDetector.hxx    |    3 
 vcl/qa/cppunit/GraphicFormatDetectorTest.cxx |   12 +-
 vcl/qa/cppunit/GraphicTest.cxx               |    2 
 vcl/source/filter/GraphicFormatDetector.cxx  |   52 ++++++++++--
 vcl/source/filter/graphicfilter2.cxx         |  116 +++------------------------
 vcl/source/graphic/UnoGraphicDescriptor.cxx  |    2 
 7 files changed, 73 insertions(+), 118 deletions(-)

New commits:
commit d5472c797df5831bb95650ad8f3c0cf94512b819
Author:     offtkp <[email protected]>
AuthorDate: Tue Aug 9 23:24:58 2022 +0300
Commit:     Tomaž Vajngerl <[email protected]>
CommitDate: Fri Aug 19 10:24:43 2022 +0200

    Remove code duplication in GraphicDescriptor for WMF/EMF
    
    GraphicFormatDetector and GraphicDescriptor have duplicate format
    detection code so now GraphicDescriptor uses GraphicFormatDetector
    functions instead to detect the format for WMF/EMF files and their Z
    compressed counterparts WMZ/EMZ
    
    Change-Id: Ia054c782320923aaa0c2c8bda2f33c27c3b123d1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138067
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <[email protected]>

diff --git a/filter/source/msfilter/escherex.cxx 
b/filter/source/msfilter/escherex.cxx
index 17c93f611d77..52326112d994 100644
--- a/filter/source/msfilter/escherex.cxx
+++ b/filter/source/msfilter/escherex.cxx
@@ -1633,7 +1633,9 @@ bool 
EscherPropertyContainer::CreateGraphicProperties(const uno::Reference<beans
                   nFormat != GraphicFileFormat::TIF &&
                   nFormat != GraphicFileFormat::PCT &&
                   nFormat != GraphicFileFormat::WMF &&
-                  nFormat != GraphicFileFormat::EMF) )
+                  nFormat != GraphicFileFormat::WMZ &&
+                  nFormat != GraphicFileFormat::EMF &&
+                  nFormat != GraphicFileFormat::EMZ) )
             {
                 std::unique_ptr<SvStream> 
pIn(::utl::UcbStreamHelper::CreateStream(
                     aTmp.GetMainURL( INetURLObject::DecodeMechanism::NONE ), 
StreamMode::READ ));
diff --git a/vcl/inc/graphic/GraphicFormatDetector.hxx 
b/vcl/inc/graphic/GraphicFormatDetector.hxx
index a9cb94320a0b..103519b6870c 100644
--- a/vcl/inc/graphic/GraphicFormatDetector.hxx
+++ b/vcl/inc/graphic/GraphicFormatDetector.hxx
@@ -157,7 +157,8 @@ public:
 
     bool checkMET();
     bool checkBMP();
-    bool checkWMForEMF();
+    bool checkWMF();
+    bool checkEMF();
     bool checkPCX();
     bool checkTIF();
     bool checkGIF();
diff --git a/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx 
b/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx
index df7f552b15af..30cd8f9ebe1e 100644
--- a/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx
+++ b/vcl/qa/cppunit/GraphicFormatDetectorTest.cxx
@@ -117,7 +117,7 @@ void GraphicFormatDetectorTest::testDetectWMF()
     vcl::GraphicFormatDetector aDetector(aFileStream, "WMF");
 
     CPPUNIT_ASSERT(aDetector.detect());
-    CPPUNIT_ASSERT(aDetector.checkWMForEMF());
+    CPPUNIT_ASSERT(aDetector.checkWMF());
 
     aFileStream.Seek(aDetector.mnStreamPosition);
 
@@ -129,10 +129,10 @@ void GraphicFormatDetectorTest::testDetectWMF()
 void GraphicFormatDetectorTest::testDetectWMZ()
 {
     SvFileStream aFileStream(getFullUrl(u"TypeDetectionExample.wmz"), 
StreamMode::READ);
-    vcl::GraphicFormatDetector aDetector(aFileStream, "WMF");
+    vcl::GraphicFormatDetector aDetector(aFileStream, "WMZ");
 
     CPPUNIT_ASSERT(aDetector.detect());
-    CPPUNIT_ASSERT(aDetector.checkWMForEMF());
+    CPPUNIT_ASSERT(aDetector.checkWMF());
 
     aFileStream.Seek(aDetector.mnStreamPosition);
 
@@ -357,7 +357,7 @@ void GraphicFormatDetectorTest::testDetectEMF()
     vcl::GraphicFormatDetector aDetector(aFileStream, "EMF");
 
     CPPUNIT_ASSERT(aDetector.detect());
-    CPPUNIT_ASSERT(aDetector.checkWMForEMF());
+    CPPUNIT_ASSERT(aDetector.checkEMF());
 
     aFileStream.Seek(aDetector.mnStreamPosition);
 
@@ -369,10 +369,10 @@ void GraphicFormatDetectorTest::testDetectEMF()
 void GraphicFormatDetectorTest::testDetectEMZ()
 {
     SvFileStream aFileStream(getFullUrl(u"TypeDetectionExample.emz"), 
StreamMode::READ);
-    vcl::GraphicFormatDetector aDetector(aFileStream, "EMF");
+    vcl::GraphicFormatDetector aDetector(aFileStream, "EMZ");
 
     CPPUNIT_ASSERT(aDetector.detect());
-    CPPUNIT_ASSERT(aDetector.checkWMForEMF());
+    CPPUNIT_ASSERT(aDetector.checkEMF());
 
     aFileStream.Seek(aDetector.mnStreamPosition);
 
diff --git a/vcl/qa/cppunit/GraphicTest.cxx b/vcl/qa/cppunit/GraphicTest.cxx
index d5a38d70ccad..378bc7a7b55b 100644
--- a/vcl/qa/cppunit/GraphicTest.cxx
+++ b/vcl/qa/cppunit/GraphicTest.cxx
@@ -512,7 +512,7 @@ void GraphicTest::testEmfToWmfConversion()
     aGraphicStream.Seek(0);
     vcl::GraphicFormatDetector aDetector(aGraphicStream, OUString());
     CPPUNIT_ASSERT(aDetector.detect());
-    CPPUNIT_ASSERT(aDetector.checkWMForEMF());
+    CPPUNIT_ASSERT(aDetector.checkWMF());
 
     // Without the accompanying fix in place, this test would have failed with:
     // - Expected: WMF
diff --git a/vcl/source/filter/GraphicFormatDetector.cxx 
b/vcl/source/filter/GraphicFormatDetector.cxx
index e2345208d6f6..684298ac773a 100644
--- a/vcl/source/filter/GraphicFormatDetector.cxx
+++ b/vcl/source/filter/GraphicFormatDetector.cxx
@@ -74,7 +74,7 @@ bool peekGraphicFormat(SvStream& rStream, OUString& 
rFormatExtension, bool bTest
         || rFormatExtension.startsWith("EMF") || 
rFormatExtension.startsWith("EMZ"))
     {
         bSomethingTested = true;
-        if (aDetector.checkWMForEMF())
+        if (aDetector.checkWMF() || aDetector.checkEMF())
         {
             rFormatExtension = 
getImportFormatShortName(aDetector.getMetadata().mnFormat);
             return true;
@@ -457,14 +457,14 @@ bool GraphicFormatDetector::checkBMP()
     return false;
 }
 
-bool GraphicFormatDetector::checkWMForEMF()
+bool GraphicFormatDetector::checkWMF()
 {
     sal_uInt64 nCheckSize = std::min<sal_uInt64>(mnStreamLength, 256);
     sal_uInt8 sExtendedOrDecompressedFirstBytes[WMF_EMF_CHECK_SIZE];
     sal_uInt64 nDecompressedSize = nCheckSize;
-    // check if it is gzipped -> wmz/emz
-    sal_uInt8* pCheckArray = 
checkAndUncompressBuffer(sExtendedOrDecompressedFirstBytes,
-                                                      WMF_EMF_CHECK_SIZE, 
nDecompressedSize);
+    // check if it is gzipped -> wmz
+    checkAndUncompressBuffer(sExtendedOrDecompressedFirstBytes, 
WMF_EMF_CHECK_SIZE,
+                             nDecompressedSize);
     if (mnFirstLong == 0xd7cdc69a || mnFirstLong == 0x01000900)
     {
         if (mbWasCompressed)
@@ -473,13 +473,51 @@ bool GraphicFormatDetector::checkWMForEMF()
             maMetadata.mnFormat = GraphicFileFormat::WMF;
         return true;
     }
-    else if (mnFirstLong == 0x01000000 && pCheckArray[40] == 0x20 && 
pCheckArray[41] == 0x45
-             && pCheckArray[42] == 0x4d && pCheckArray[43] == 0x46)
+    return false;
+}
+
+bool GraphicFormatDetector::checkEMF()
+{
+    sal_uInt64 nCheckSize = std::min<sal_uInt64>(mnStreamLength, 256);
+    sal_uInt8 sExtendedOrDecompressedFirstBytes[WMF_EMF_CHECK_SIZE];
+    sal_uInt64 nDecompressedSize = nCheckSize;
+    // check if it is gzipped -> emz
+    sal_uInt8* pCheckArray = 
checkAndUncompressBuffer(sExtendedOrDecompressedFirstBytes,
+                                                      WMF_EMF_CHECK_SIZE, 
nDecompressedSize);
+    if (mnFirstLong == 0x01000000 && pCheckArray[40] == 0x20 && 
pCheckArray[41] == 0x45
+        && pCheckArray[42] == 0x4d && pCheckArray[43] == 0x46)
     {
         if (mbWasCompressed)
             maMetadata.mnFormat = GraphicFileFormat::EMZ;
         else
             maMetadata.mnFormat = GraphicFileFormat::EMF;
+        if (mbExtendedInfo)
+        {
+            sal_Int32 nBoundLeft = 0, nBoundTop = 0, nBoundRight = 0, 
nBoundBottom = 0;
+            sal_Int32 nFrameLeft = 0, nFrameTop = 0, nFrameRight = 0, 
nFrameBottom = 0;
+            nBoundLeft = pCheckArray[8] | (pCheckArray[9] << 8) | 
(pCheckArray[10] << 16)
+                         | (pCheckArray[11] << 24);
+            nBoundTop = pCheckArray[12] | (pCheckArray[13] << 8) | 
(pCheckArray[14] << 16)
+                        | (pCheckArray[15] << 24);
+            nBoundRight = pCheckArray[16] | (pCheckArray[17] << 8) | 
(pCheckArray[18] << 16)
+                          | (pCheckArray[19] << 24);
+            nBoundBottom = pCheckArray[20] | (pCheckArray[21] << 8) | 
(pCheckArray[22] << 16)
+                           | (pCheckArray[23] << 24);
+            nFrameLeft = pCheckArray[24] | (pCheckArray[25] << 8) | 
(pCheckArray[26] << 16)
+                         | (pCheckArray[27] << 24);
+            nFrameTop = pCheckArray[28] | (pCheckArray[29] << 8) | 
(pCheckArray[30] << 16)
+                        | (pCheckArray[31] << 24);
+            nFrameRight = pCheckArray[32] | (pCheckArray[33] << 8) | 
(pCheckArray[34] << 16)
+                          | (pCheckArray[35] << 24);
+            nFrameBottom = pCheckArray[36] | (pCheckArray[37] << 8) | 
(pCheckArray[38] << 16)
+                           | (pCheckArray[39] << 24);
+            // size in pixels
+            maMetadata.maPixSize.setWidth(nBoundRight - nBoundLeft + 1);
+            maMetadata.maPixSize.setHeight(nBoundBottom - nBoundTop + 1);
+            // size in 0.01mm units
+            maMetadata.maLogSize.setWidth(nFrameRight - nFrameLeft + 1);
+            maMetadata.maLogSize.setHeight(nFrameBottom - nFrameTop + 1);
+        }
         return true;
     }
     return false;
diff --git a/vcl/source/filter/graphicfilter2.cxx 
b/vcl/source/filter/graphicfilter2.cxx
index 8ce85ee1f9df..ea9e5a9480d7 100644
--- a/vcl/source/filter/graphicfilter2.cxx
+++ b/vcl/source/filter/graphicfilter2.cxx
@@ -31,11 +31,6 @@
 #include "graphicfilter_internal.hxx"
 
 #define DATA_SIZE           640
-constexpr sal_uInt32 EMF_CHECK_SIZE      = 44;
-constexpr sal_uInt32 WMF_CHECK_SIZE      = 32;
-constexpr sal_uInt32 EMR_HEADER          = 0x00000001;
-constexpr sal_uInt32 ENHMETA_SIGNATURE   = 0x464d4520;
-constexpr sal_uInt32 PLACEABLE_SIGNATURE = 0x9ac6cdd7;
 namespace
 {
 enum class MetafileType : sal_uInt16
@@ -1071,110 +1066,27 @@ bool GraphicDescriptor::ImpDetectSVM( SvStream& rStm, 
bool bExtendedInfo )
     return bRet;
 }
 
-bool GraphicDescriptor::ImpDetectWMF(SvStream& rStm, bool)
+bool GraphicDescriptor::ImpDetectWMF(SvStream& rStm, bool /*bExtendedInfo*/)
 {
-    bool bRet = false;
-    SvStream* aNewStream = &rStm;
-    SvMemoryStream aMemStream;
-    sal_uInt8 aUncompressedBuffer[WMF_CHECK_SIZE];
-    if (ZCodec::IsZCompressed(rStm))
-    {
-        ZCodec aCodec;
-        aCodec.BeginCompression(ZCODEC_DEFAULT_COMPRESSION, /*gzLib*/ true);
-        auto nDecompressLength = aCodec.Read(rStm, aUncompressedBuffer, 
WMF_CHECK_SIZE);
-        aCodec.EndCompression();
-        if (nDecompressLength != WMF_CHECK_SIZE)
-            return false;
-        aMemStream.SetBuffer(aUncompressedBuffer, WMF_CHECK_SIZE, 
WMF_CHECK_SIZE);
-        aNewStream = &aMemStream;
-    }
-    sal_uInt32 nKey = 0;
     sal_Int32 nStmPos = rStm.Tell();
-    aNewStream->SetEndian(SvStreamEndian::LITTLE);
-    aNewStream->ReadUInt32(nKey);
-    // Check if file is placeable WMF
-    if (nKey == PLACEABLE_SIGNATURE)
-    {
-        aMetadata.mnFormat = GraphicFileFormat::WMF;
-        bRet = true;
-    }
-    else
-    {
-        sal_uInt16 nKeyLSW = nKey & 0xFFFF;
-        sal_uInt16 nVersion = 0;
-        aNewStream->ReadUInt16(nVersion);
-        if ((nKeyLSW == static_cast<sal_uInt16>(MetafileType::Memory)
-            || nKeyLSW == static_cast<sal_uInt16>(MetafileType::Disk))
-            && (nVersion == 
static_cast<sal_uInt16>(MetafileVersion::Version100)
-            || nVersion == 
static_cast<sal_uInt16>(MetafileVersion::Version300)))
-        {
-            aMetadata.mnFormat = GraphicFileFormat::WMF;
-            bRet = true;
-        }
-    }
-
-    rStm.Seek(nStmPos);
+    vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false 
/*bExtendedInfo*/ );
+    bool bRet = aDetector.detect();
+    bRet &= aDetector.checkWMF();
+    if ( bRet )
+        aMetadata = aDetector.getMetadata();
+    rStm.Seek( nStmPos );
     return bRet;
 }
 
 bool GraphicDescriptor::ImpDetectEMF(SvStream& rStm, bool bExtendedInfo)
 {
-    SvStream* aNewStream = &rStm;
-    SvMemoryStream aMemStream;
-    sal_uInt8 aUncompressedBuffer[EMF_CHECK_SIZE];
-    if (ZCodec::IsZCompressed(rStm))
-    {
-        ZCodec aCodec;
-        aCodec.BeginCompression(ZCODEC_DEFAULT_COMPRESSION, /*gzLib*/ true);
-        auto nDecompressLength = aCodec.Read(rStm, aUncompressedBuffer, 
EMF_CHECK_SIZE);
-        aCodec.EndCompression();
-        if (nDecompressLength != EMF_CHECK_SIZE)
-            return false;
-        aMemStream.SetBuffer(aUncompressedBuffer, EMF_CHECK_SIZE, 
EMF_CHECK_SIZE);
-        aNewStream = &aMemStream;
-    }
-
-    sal_uInt32 nRecordType = 0;
-    bool bRet = false;
-    sal_Int32 nStmPos = aNewStream->Tell();
-    aNewStream->SetEndian(SvStreamEndian::LITTLE);
-    aNewStream->ReadUInt32(nRecordType);
-    if (nRecordType == EMR_HEADER)
-    {
-        sal_Int32 nBoundLeft = 0, nBoundTop = 0, nBoundRight = 0, nBoundBottom 
= 0;
-        sal_Int32 nFrameLeft = 0, nFrameTop = 0, nFrameRight = 0, nFrameBottom 
= 0;
-        sal_uInt32 nSignature = 0;
-
-        aNewStream->SeekRel(4);
-        aNewStream->ReadInt32(nBoundLeft);
-        aNewStream->ReadInt32(nBoundTop);
-        aNewStream->ReadInt32(nBoundRight);
-        aNewStream->ReadInt32(nBoundBottom);
-        aNewStream->ReadInt32(nFrameLeft);
-        aNewStream->ReadInt32(nFrameTop);
-        aNewStream->ReadInt32(nFrameRight);
-        aNewStream->ReadInt32(nFrameBottom);
-        aNewStream->ReadUInt32(nSignature);
-
-        if (nSignature == ENHMETA_SIGNATURE)
-        {
-            aMetadata.mnFormat = GraphicFileFormat::EMF;
-            bRet = true;
-
-            if (bExtendedInfo)
-            {
-                // size in pixels
-                aMetadata.maPixSize.setWidth(nBoundRight - nBoundLeft + 1);
-                aMetadata.maPixSize.setHeight(nBoundBottom - nBoundTop + 1);
-
-                // size in 0.01mm units
-                aMetadata.maLogSize.setWidth(nFrameRight - nFrameLeft + 1);
-                aMetadata.maLogSize.setHeight(nFrameBottom - nFrameTop + 1);
-            }
-        }
-    }
-
-    rStm.Seek(nStmPos);
+    sal_Int32 nStmPos = rStm.Tell();
+    vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
+    bool bRet = aDetector.detect();
+    bRet &= aDetector.checkEMF();
+    if ( bRet )
+        aMetadata = aDetector.getMetadata();
+    rStm.Seek( nStmPos );
     return bRet;
 }
 
diff --git a/vcl/source/graphic/UnoGraphicDescriptor.cxx 
b/vcl/source/graphic/UnoGraphicDescriptor.cxx
index 74a99eb0a610..ca25e5c6d964 100644
--- a/vcl/source/graphic/UnoGraphicDescriptor.cxx
+++ b/vcl/source/graphic/UnoGraphicDescriptor.cxx
@@ -135,7 +135,9 @@ void GraphicDescriptor::implCreate( SvStream& rIStm, const 
OUString* pURL )
         case GraphicFileFormat::PCT: pMimeType = MIMETYPE_PCT; cType = 
graphic::GraphicType::VECTOR; break;
         case GraphicFileFormat::SVM: pMimeType = MIMETYPE_SVM; cType = 
graphic::GraphicType::VECTOR; break;
         case GraphicFileFormat::WMF: pMimeType = MIMETYPE_WMF; cType = 
graphic::GraphicType::VECTOR; break;
+        case GraphicFileFormat::WMZ: pMimeType = MIMETYPE_WMF; cType = 
graphic::GraphicType::VECTOR; break;
         case GraphicFileFormat::EMF: pMimeType = MIMETYPE_EMF; cType = 
graphic::GraphicType::VECTOR; break;
+        case GraphicFileFormat::EMZ: pMimeType = MIMETYPE_EMF; cType = 
graphic::GraphicType::VECTOR; break;
         case GraphicFileFormat::SVG: pMimeType = MIMETYPE_SVG; cType = 
graphic::GraphicType::VECTOR; break;
 
         default:

Reply via email to