diff options
author | offtkp <parisoplop@gmail.com> | 2022-05-21 11:23:01 +0300 |
---|---|---|
committer | Bartosz Kosiorek <gang65@poczta.onet.pl> | 2022-05-24 08:19:41 +0200 |
commit | 063d641f023ac90f49116de105e32e38be72a1af (patch) | |
tree | 1cfcc8920951624819eddabcf67e59c25ecc1d2d | |
parent | cef860d8fd1c6952bac74053928107d048d16528 (diff) |
tdf#149206 Set size correctly when loading EMF
Regression fixed, rolled back ImpDetectEMF function
to version before https://gerrit.libreoffice.org/c/core/+/132456,
changed type detection from extension checking back to
magic number checking. Also added a small uncompression
at the start to keep EMZ support.
Change-Id: Id4489da399a571c4c72ce137f841614f5c0d7bdc
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134703
Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
Tested-by: Jenkins
-rw-r--r-- | vcl/source/filter/graphicfilter2.cxx | 64 |
1 files changed, 60 insertions, 4 deletions
diff --git a/vcl/source/filter/graphicfilter2.cxx b/vcl/source/filter/graphicfilter2.cxx index eaef61b1d1e1..c02e9d557c44 100644 --- a/vcl/source/filter/graphicfilter2.cxx +++ b/vcl/source/filter/graphicfilter2.cxx @@ -21,6 +21,7 @@ #include <tools/stream.hxx> #include <tools/fract.hxx> #include <tools/urlobj.hxx> +#include <tools/zcodec.hxx> #include <vcl/TypeSerializer.hxx> #include <vcl/outdev.hxx> #include <vcl/graphicfilter.hxx> @@ -29,6 +30,9 @@ #include "graphicfilter_internal.hxx" #define DATA_SIZE 640 +constexpr sal_uInt32 EMF_CHECK_SIZE = 44; +constexpr sal_uInt32 EMR_HEADER = 0x00000001; +constexpr sal_uInt32 ENHMETA_SIGNATURE = 0x464d4520; GraphicDescriptor::GraphicDescriptor( const INetURLObject& rPath ) : pFileStm( ::utl::UcbStreamHelper::CreateStream( rPath.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ).release() ), @@ -1086,12 +1090,64 @@ bool GraphicDescriptor::ImpDetectWMF( SvStream&, bool ) return bRet; } -bool GraphicDescriptor::ImpDetectEMF( SvStream&, bool ) +bool GraphicDescriptor::ImpDetectEMF(SvStream& rStm, bool bExtendedInfo) { - bool bRet = aPathExt.startsWith( "emf" ) || aPathExt.startsWith( "emz" ); - if (bRet) - nFormat = GraphicFileFormat::EMF; + 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) + { + nFormat = GraphicFileFormat::EMF; + bRet = true; + + if (bExtendedInfo) + { + // size in pixels + aPixSize.setWidth(nBoundRight - nBoundLeft + 1); + aPixSize.setHeight(nBoundBottom - nBoundTop + 1); + + // size in 0.01mm units + aLogSize.setWidth(nFrameRight - nFrameLeft + 1); + aLogSize.setHeight(nFrameBottom - nFrameTop + 1); + } + } + } + rStm.Seek(nStmPos); return bRet; } |