diff options
author | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2020-04-20 21:40:10 +0200 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2020-04-20 21:42:59 +0200 |
commit | 4b62c2cb22cead8332bf2b8323e203717a3857d6 (patch) | |
tree | ac961bd25a1ccb69fed9d71fe33db6c212a9273b | |
parent | Catch deployment exception; extmgr is not functional (diff) | |
download | core-4b62c2cb22cead8332bf2b8323e203717a3857d6.tar.gz core-4b62c2cb22cead8332bf2b8323e203717a3857d6.zip |
pdf export: be a bit less wasteful when jpeg-optimising bitmaps
Before, code was test-compressing every single bitmap coming along.
Let's buffer those SvMemStreams, and keep the last 10 around in
case the same image comes along again.
Change-Id: Ic8da32725ea46b01bd6beacc389abf8f52845d36
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl2.cxx | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/vcl/source/gdi/pdfwriter_impl2.cxx b/vcl/source/gdi/pdfwriter_impl2.cxx index 5e5c0e5fbf6a..4dfbce8ce44a 100644 --- a/vcl/source/gdi/pdfwriter_impl2.cxx +++ b/vcl/source/gdi/pdfwriter_impl2.cxx @@ -49,6 +49,7 @@ #include <rtl/digest.h> #include <sal/log.hxx> #include <memory> +#include <deque> using namespace vcl; using namespace com::sun::star; @@ -57,6 +58,11 @@ using namespace com::sun::star::beans; static bool lcl_canUsePDFAxialShading(const Gradient& rGradient); +/// Cache some last 10 bitmaps we've exported, in case we encounter them again.. +static const long nPDFBmpCacheMaxSize = 10; +typedef std::pair<BitmapChecksum, std::shared_ptr<SvMemoryStream>> ImpCacheEntry; +static std::deque< ImpCacheEntry > lcl_PDFBmpCache; + void PDFWriterImpl::implWriteGradient( const tools::PolyPolygon& i_rPolyPoly, const Gradient& i_rGradient, VirtualDevice* i_pDummyVDev, const vcl::PDFWriter::PlayMetafileContext& i_rContext ) { @@ -169,13 +175,28 @@ void PDFWriterImpl::implWriteBitmapEx( const Point& i_rPoint, const Size& i_rSiz if ( bIsPng || ( aSizePixel.Width() < 32 ) || ( aSizePixel.Height() < 32 ) ) bUseJPGCompression = false; - SvMemoryStream aStrm; - Bitmap aMask; + std::shared_ptr<SvMemoryStream> pStrm(new SvMemoryStream()); + Bitmap aMask; bool bTrueColorJPG = true; if ( bUseJPGCompression ) { - + // TODO this checks could be done much earlier, saving us + // from trying conversion & stores before... + if ( !aBitmapEx.IsTransparent() ) + { + const auto& rCacheEntry= + std::find_if(lcl_PDFBmpCache.begin(), lcl_PDFBmpCache.end(), + [&](const ImpCacheEntry& val) { + return val.first == aBitmapEx.GetChecksum(); + }); + if ( rCacheEntry != lcl_PDFBmpCache.end() ) + { + m_rOuterFace.DrawJPGBitmap( *rCacheEntry->second, true, aSizePixel, + tools::Rectangle( aPoint, aSize ), aMask, i_Graphic ); + return; + } + } sal_uInt32 nZippedFileSize = 0; // sj: we will calculate the filesize of a zipped bitmap if ( !bIsJpeg ) // to determine if jpeg compression is useful { @@ -202,7 +223,7 @@ void PDFWriterImpl::implWriteBitmapEx( const Point& i_rPoint, const Size& i_rSiz try { - uno::Reference < io::XStream > xStream = new utl::OStreamWrapper( aStrm ); + uno::Reference < io::XStream > xStream = new utl::OStreamWrapper( *pStrm ); uno::Reference< io::XSeekable > xSeekable( xStream, UNO_QUERY_THROW ); uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() ); uno::Reference< graphic::XGraphicProvider > xGraphicProvider( graphic::GraphicProvider::create(xContext) ); @@ -223,7 +244,7 @@ void PDFWriterImpl::implWriteBitmapEx( const Point& i_rPoint, const Size& i_rSiz } else { - aStrm.Seek( STREAM_SEEK_TO_END ); + pStrm->Seek( STREAM_SEEK_TO_END ); xSeekable->seek( 0 ); Sequence< PropertyValue > aArgs( 1 ); @@ -246,7 +267,18 @@ void PDFWriterImpl::implWriteBitmapEx( const Point& i_rPoint, const Size& i_rSiz } } if ( bUseJPGCompression ) - m_rOuterFace.DrawJPGBitmap( aStrm, bTrueColorJPG, aSizePixel, tools::Rectangle( aPoint, aSize ), aMask, i_Graphic ); + { + m_rOuterFace.DrawJPGBitmap( *pStrm, bTrueColorJPG, aSizePixel, tools::Rectangle( aPoint, aSize ), aMask, i_Graphic ); + if (!aBitmapEx.IsTransparent() && bTrueColorJPG) + { + // Cache last jpeg export + lcl_PDFBmpCache.push_back( + std::make_pair( + aBitmapEx.GetChecksum(), pStrm)); + if ( lcl_PDFBmpCache.size() > nPDFBmpCacheMaxSize ) + lcl_PDFBmpCache.pop_front(); + } + } else if ( aBitmapEx.IsTransparent() ) m_rOuterFace.DrawBitmapEx( aPoint, aSize, aBitmapEx ); else |