From 5ae10ae4df7180d4464f85586232cb7dc106ed5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=C5=BE=20Vajngerl?= Date: Wed, 3 Jun 2015 20:11:33 +0900 Subject: [PATCH] graphicfilter: store the funky animated GIF in a PNG as a GIF MS had a really bad idea to store an animated GIF inside a PNG for some reason. This situation was handled correctly in LO but we still pretended that this was a PNG file, which was causing confusion for some users that wanted to extract the image from the document. With this change we extract the animated GIF from the PNG and store just the GIF in the document. Change-Id: I4c70d118e8decd7aa1b108b6b1d725301904a35b --- vcl/source/filter/graphicfilter.cxx | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx index 0a8afa2d0407..0a2cd01a93b3 100644 --- a/vcl/source/filter/graphicfilter.cxx +++ b/vcl/source/filter/graphicfilter.cxx @@ -1455,21 +1455,28 @@ sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPat else { // check if this PNG contains a GIF chunk! - const std::vector< vcl::PNGReader::ChunkData >& rChunkData = aPNGReader.GetChunks(); - std::vector< vcl::PNGReader::ChunkData >::const_iterator aIter( rChunkData.begin() ); - std::vector< vcl::PNGReader::ChunkData >::const_iterator aEnd ( rChunkData.end() ); - while( aIter != aEnd ) + const std::vector& rChunkData = aPNGReader.GetChunks(); + std::vector::const_iterator aIter(rChunkData.begin()); + std::vector::const_iterator aEnd(rChunkData.end()); + + while (aIter != aEnd) { // Microsoft Office is storing Animated GIFs in following chunk - if ( aIter->nType == PMGCHUNG_msOG ) + if (aIter->nType == PMGCHUNG_msOG) { sal_uInt32 nChunkSize = aIter->aData.size(); - if ( nChunkSize > 11 ) + + if (nChunkSize > 11) { - const std::vector< sal_uInt8 >& rData = aIter->aData; - SvMemoryStream aIStrm( (void*)&rData[ 11 ], nChunkSize - 11, StreamMode::READ ); - ImportGIF( aIStrm, rGraphic ); - eLinkType = GFX_LINK_TYPE_NATIVE_PNG; + const std::vector& rData = aIter->aData; + nGraphicContentSize = nChunkSize - 11; + SvMemoryStream aIStrm(const_cast(&rData[11]), nGraphicContentSize, StreamMode::READ); + pGraphicContent = new sal_uInt8[nGraphicContentSize]; + sal_uInt64 aCurrentPosition = aIStrm.Tell(); + aIStrm.Read(pGraphicContent, nGraphicContentSize); + aIStrm.Seek(aCurrentPosition); + ImportGIF(aIStrm, rGraphic); + eLinkType = GFX_LINK_TYPE_NATIVE_GIF; break; } } @@ -1520,6 +1527,7 @@ sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPat rIStream.Seek(nStreamPosition); rIStream.Read(&aTwoBytes[0], 2); rIStream.Seek(nStreamPosition); + if(aTwoBytes[0] == 0x1F && aTwoBytes[1] == 0x8B) { SvMemoryStream aMemStream;