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 15 around in case the same image comes along again. Change-Id: Ic8da32725ea46b01bd6beacc389abf8f52845d36 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93058 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
#include <com/sun/star/beans/XMaterialHolder.hpp>
|
||||
|
||||
#include <cppuhelper/implbase.hxx>
|
||||
#include <o3tl/lru_map.hxx>
|
||||
|
||||
#include <sal/log.hxx>
|
||||
#include <memory>
|
||||
@@ -54,6 +55,9 @@ using namespace com::sun::star::beans;
|
||||
|
||||
static bool lcl_canUsePDFAxialShading(const Gradient& rGradient);
|
||||
|
||||
/// Cache some last 15 bitmaps we've exported, in case we encounter them again..
|
||||
static o3tl::lru_map<BitmapChecksum, std::shared_ptr<SvMemoryStream>> lcl_PDFBmpCache(15);
|
||||
|
||||
void PDFWriterImpl::implWriteGradient( const tools::PolyPolygon& i_rPolyPoly, const Gradient& i_rGradient,
|
||||
VirtualDevice* i_pDummyVDev, const vcl::PDFWriter::PlayMetafileContext& i_rContext )
|
||||
{
|
||||
@@ -168,13 +172,25 @@ 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;
|
||||
auto pStrm=std::make_shared<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=lcl_PDFBmpCache.find(
|
||||
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
|
||||
{
|
||||
@@ -201,7 +217,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) );
|
||||
@@ -222,7 +238,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 );
|
||||
@@ -245,7 +261,15 @@ 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.insert(
|
||||
{aBitmapEx.GetChecksum(), pStrm});
|
||||
}
|
||||
}
|
||||
else if ( aBitmapEx.IsTransparent() )
|
||||
m_rOuterFace.DrawBitmapEx( aPoint, aSize, aBitmapEx );
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user