[Libreoffice-commits] core.git: Branch 'feature/cib_contract4236' - vcl/source

Thorsten Behrens (via logerrit) logerrit at kemper.freedesktop.org
Mon Apr 20 19:43:39 UTC 2020


 vcl/source/gdi/pdfwriter_impl2.cxx |   44 +++++++++++++++++++++++++++++++------
 1 file changed, 38 insertions(+), 6 deletions(-)

New commits:
commit 4b62c2cb22cead8332bf2b8323e203717a3857d6
Author:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
AuthorDate: Mon Apr 20 21:40:10 2020 +0200
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Mon Apr 20 21:42:59 2020 +0200

    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

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


More information about the Libreoffice-commits mailing list