Kaydet (Commit) c77c6c2a authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl

Support svgz in graphicfilter (import image to document)

Detect if input stream is gzip, if it is decompress and check the
decompressed stream if the content is svg.
When reading, decompress the whole svg content first, and then
store it internally.

Change-Id: Ie8b7e2b2f59a92d6420c38fd4a25637a6ee94425
üst 15f90918
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <ucbhelper/content.hxx> #include <ucbhelper/content.hxx>
#include <cppuhelper/implbase1.hxx> #include <cppuhelper/implbase1.hxx>
#include <tools/urlobj.hxx> #include <tools/urlobj.hxx>
#include <tools/zcodec.hxx>
#include <vcl/dibtools.hxx> #include <vcl/dibtools.hxx>
#include <vcl/salctype.hxx> #include <vcl/salctype.hxx>
#include <vcl/pngread.hxx> #include <vcl/pngread.hxx>
...@@ -645,81 +646,73 @@ static bool ImpPeekGraphicFormat( SvStream& rStream, OUString& rFormatExtension, ...@@ -645,81 +646,73 @@ static bool ImpPeekGraphicFormat( SvStream& rStream, OUString& rFormatExtension,
//--------------------------- SVG ------------------------------------ //--------------------------- SVG ------------------------------------
if( !bTest ) if( !bTest )
{ {
// check for Xml sal_uInt8* pCheckArray = sFirstBytes;
if( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"<?xml", 256, 5 ) // is it xml sal_uLong nCheckSize = nStreamLen < 256 ? nStreamLen : 256;
&& ImplSearchEntry( sFirstBytes, (sal_uInt8*)"version", 256, 7 )) // does it have a version (required for xml)
sal_uInt8 sExtendedOrDecompressedFirstBytes[2048];
sal_uLong nDecompressedSize = nCheckSize;
bool bIsGZip(false);
// check if it is gzipped -> svgz
if(sFirstBytes[0] == 0x1F && sFirstBytes[1] == 0x8B)
{ {
GZCodec aCodec;
rStream.Seek(nStreamPos);
aCodec.BeginCompression();
nDecompressedSize = aCodec.Read(rStream, sExtendedOrDecompressedFirstBytes, 2048);
nCheckSize = nDecompressedSize < 256 ? nDecompressedSize : 256;
aCodec.EndCompression();
pCheckArray = sExtendedOrDecompressedFirstBytes;
}
bool bIsSvg(false); bool bIsSvg(false);
// check for Xml
// #119176# SVG files which have no xml header at all have shown up this is optional
if( ImplSearchEntry(pCheckArray, (sal_uInt8*)"<?xml", nCheckSize, 5 ) // is it xml
&& ImplSearchEntry(pCheckArray, (sal_uInt8*)"version", nCheckSize, 7 )) // does it have a version (required for xml)
{
// check for DOCTYPE svg combination // check for DOCTYPE svg combination
if( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"DOCTYPE", 256, 7 ) // 'DOCTYPE' is there if( ImplSearchEntry(pCheckArray, (sal_uInt8*)"DOCTYPE", nCheckSize, 7 ) // 'DOCTYPE' is there
&& ImplSearchEntry( sFirstBytes, (sal_uInt8*)"svg", 256, 3 )) // 'svg' is there && ImplSearchEntry(pCheckArray, (sal_uInt8*)"svg", nCheckSize, 3 )) // 'svg' is there
{ {
bIsSvg = true; bIsSvg = true;
} }
}
// check for svg element in 1st 256 bytes // check for svg element in 1st 256 bytes
if(!bIsSvg && ImplSearchEntry( sFirstBytes, (sal_uInt8*)"<svg", 256, 4 )) // '<svg' if(!bIsSvg && ImplSearchEntry(pCheckArray, (sal_uInt8*)"<svg", nCheckSize, 4 )) // '<svg'
{ {
bIsSvg = true; bIsSvg = true;
} }
// extended search for svg element
if(!bIsSvg) if(!bIsSvg)
{ {
// it's a xml, look for '<svg' in full file. Should not happen too // it's a xml, look for '<svg' in full file. Should not happen too
// often since the tests above will handle most cases, but can happen // often since the tests above will handle most cases, but can happen
// with Svg files containing big comment headers or Svg as the host // with Svg files containing big comment headers or Svg as the host
// language // language
const sal_uLong nSize((nStreamLen > 2048) ? 2048 : nStreamLen);
sal_uInt8* pBuf = new sal_uInt8[nSize];
rStream.Seek(nStreamPos); pCheckArray = sExtendedOrDecompressedFirstBytes;
rStream.Read(pBuf, nSize);
if(ImplSearchEntry(pBuf, (sal_uInt8*)"<svg", nSize, 4)) // '<svg' if(!bIsGZip)
{ {
bIsSvg = true; nCheckSize = nDecompressedSize < 2048 ? nDecompressedSize : 2048;
}
delete[] pBuf;
}
if(bIsSvg)
{
rFormatExtension = "SVG";
return true;
}
} }
else else
{ {
// #119176# SVG files which have no xml header at all have shown up, nCheckSize = nStreamLen < 2048 ? nStreamLen : 2048;
// detect those, too
bool bIsSvg(false);
// check for svg element in 1st 256 bytes
if(ImplSearchEntry( sFirstBytes, (sal_uInt8*)"<svg", 256, 4 )) // '<svg'
{
bIsSvg = true;
}
if(!bIsSvg)
{
// look for '<svg' in full file. Should not happen too
// often since the tests above will handle most cases, but can happen
// with SVG files containing big comment headers or SVG as the host
// language
const sal_uLong nSize((nStreamLen > 2048) ? 2048 : nStreamLen);
sal_uInt8* pBuf = new sal_uInt8[nSize];
rStream.Seek(nStreamPos); rStream.Seek(nStreamPos);
rStream.Read(pBuf, nSize); rStream.Read(sExtendedOrDecompressedFirstBytes, nCheckSize);
}
if(ImplSearchEntry(pBuf, (sal_uInt8*)"<svg", nSize, 4)) // '<svg' if(ImplSearchEntry(pCheckArray, (sal_uInt8*)"<svg", nCheckSize, 4)) // '<svg'
{ {
bIsSvg = true; bIsSvg = true;
} }
delete[] pBuf;
} }
if(bIsSvg) if(bIsSvg)
...@@ -728,7 +721,6 @@ static bool ImpPeekGraphicFormat( SvStream& rStream, OUString& rFormatExtension, ...@@ -728,7 +721,6 @@ static bool ImpPeekGraphicFormat( SvStream& rStream, OUString& rFormatExtension,
return true; return true;
} }
} }
}
else if( rFormatExtension.startsWith( "SVG" ) ) else if( rFormatExtension.startsWith( "SVG" ) )
{ {
bSomethingTested = true; bSomethingTested = true;
...@@ -1521,29 +1513,55 @@ sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPat ...@@ -1521,29 +1513,55 @@ sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPat
if( rGraphic.GetContext() == (GraphicReader*) 1 ) if( rGraphic.GetContext() == (GraphicReader*) 1 )
rGraphic.SetContext( NULL ); rGraphic.SetContext( NULL );
const sal_uInt32 nStmPos(rIStream.Tell()); const sal_uInt32 nStreamPosition(rIStream.Tell());
const sal_uInt32 nStmLen(rIStream.Seek(STREAM_SEEK_TO_END) - nStmPos); const sal_uInt32 nStreamLength(rIStream.Seek(STREAM_SEEK_TO_END) - nStreamPosition);
bool bOkay(false); bool bOkay(false);
if(nStmLen) if(nStreamLength > 0)
{
std::vector<sal_uInt8> aTwoBytes(2);
rIStream.Seek(nStreamPosition);
rIStream.Read(&aTwoBytes[0], 2);
rIStream.Seek(nStreamPosition);
if(aTwoBytes[0] == 0x1F && aTwoBytes[1] == 0x8B)
{ {
SvgDataArray aNewData(new sal_uInt8[nStmLen]); SvMemoryStream aMemStream;
GZCodec aCodec;
sal_uInt32 nMemoryLength;
rIStream.Seek(nStmPos); aCodec.BeginCompression();
rIStream.Read(aNewData.get(), nStmLen); nMemoryLength = aCodec.Decompress(rIStream, aMemStream);
aCodec.EndCompression();
if(!rIStream.GetError()) if(!rIStream.GetError() )
{ {
SvgDataPtr aSvgDataPtr( SvgDataArray aNewData(new sal_uInt8[nMemoryLength]);
new SvgData( aMemStream.Seek(STREAM_SEEK_TO_BEGIN);
aNewData, aMemStream.Read(aNewData.get(), nMemoryLength);
nStmLen,
rPath));
if(!aMemStream.GetError() )
{
SvgDataPtr aSvgDataPtr(new SvgData(aNewData, nMemoryLength, rPath));
rGraphic = Graphic(aSvgDataPtr); rGraphic = Graphic(aSvgDataPtr);
bOkay = true; bOkay = true;
} }
} }
}
else
{
SvgDataArray aNewData(new sal_uInt8[nStreamLength]);
rIStream.Seek(nStreamPosition);
rIStream.Read(aNewData.get(), nStreamLength);
if(!rIStream.GetError())
{
SvgDataPtr aSvgDataPtr(new SvgData(aNewData, nStreamLength, rPath));
rGraphic = Graphic(aSvgDataPtr);
bOkay = true;
}
}
}
if(bOkay) if(bOkay)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment