[Libreoffice-commits] core.git: include/tools tools/source vcl/inc vcl/source
Jan-Marek Glogowski
glogow at fbihome.de
Mon Nov 6 14:49:49 UTC 2017
include/tools/stream.hxx | 1
tools/source/stream/stream.cxx | 21 +++++++++++
vcl/inc/pdfread.hxx | 4 ++
vcl/source/filter/graphicfilter.cxx | 2 -
vcl/source/filter/ipdf/pdfread.cxx | 66 ++++++++++++++++++++++++------------
vcl/source/gdi/impgraph.cxx | 13 ++++---
6 files changed, 79 insertions(+), 28 deletions(-)
New commits:
commit 3a88795c1211c62277dc646e61c2ba8306febe37
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date: Thu Oct 26 16:05:54 2017 +0200
tdf#108748 generate PDF preview on SwapIn
When including a PDF as an image, it's represented internally as
a Bitmap with additional PDF data. On SwapIn, LibreOffice just
imported the PDF data missing the PDF preview. The Graphic also
gad the wrong image type, which results in a busy loop on master,
with a strange / unhelpful STR_COMCORE_READERROR generated by
SwNoTextFrame::PaintPicture.
This is a workaround to generate the Bitmap on SwapIn, which
will really slow down LibreOffice when importing many PDFs.
I guess the job of generating the PDF previews should probably
be deferred to a thread or a low priority Scheduler task, just
like the general image loading is handled.
Change-Id: I8084e4533995ecddc5b03ef19cb0c6a2dbf60ebd
Reviewed-on: https://gerrit.libreoffice.org/43906
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>
diff --git a/include/tools/stream.hxx b/include/tools/stream.hxx
index 00aa872f53e3..64823f48d078 100644
--- a/include/tools/stream.hxx
+++ b/include/tools/stream.hxx
@@ -252,6 +252,7 @@ public:
SvStream& WriteOString(const OString& rStr)
{ return WriteCharPtr(rStr.getStr()); }
SvStream& WriteStream( SvStream& rStream );
+ sal_uInt64 WriteStream( SvStream& rStream, sal_uInt64 nSize );
SvStream& WriteBool( bool b )
{ return WriteUChar(static_cast<unsigned char>(b)); }
diff --git a/tools/source/stream/stream.cxx b/tools/source/stream/stream.cxx
index 4f95afd2c1e8..4c363dc67484 100644
--- a/tools/source/stream/stream.cxx
+++ b/tools/source/stream/stream.cxx
@@ -1179,6 +1179,27 @@ SvStream& SvStream::WriteStream( SvStream& rStream )
return *this;
}
+sal_uInt64 SvStream::WriteStream( SvStream& rStream, sal_uInt64 nSize )
+{
+ const sal_uInt32 cBufLen = 0x8000;
+ std::unique_ptr<char[]> pBuf( new char[ cBufLen ] );
+ sal_uInt32 nCurBufLen = cBufLen;
+ sal_uInt32 nCount;
+ sal_uInt64 nWriteSize = nSize;
+
+ do {
+ if ( nSize >= nCurBufLen )
+ nWriteSize -= nCurBufLen;
+ else
+ nCurBufLen = nWriteSize;
+ nCount = rStream.ReadBytes( pBuf.get(), nCurBufLen );
+ WriteBytes( pBuf.get(), nCount );
+ }
+ while( nWriteSize && nCount == nCurBufLen );
+
+ return nSize - nWriteSize;
+}
+
OUString SvStream::ReadUniOrByteString( rtl_TextEncoding eSrcCharSet )
{
// read UTF-16 string directly from stream ?
diff --git a/vcl/source/filter/ipdf/pdfread.hxx b/vcl/inc/pdfread.hxx
similarity index 73%
rename from vcl/source/filter/ipdf/pdfread.hxx
rename to vcl/inc/pdfread.hxx
index 2cb3abd7bc01..e873c49a1cdd 100644
--- a/vcl/source/filter/ipdf/pdfread.hxx
+++ b/vcl/inc/pdfread.hxx
@@ -17,6 +17,10 @@ namespace vcl
{
/// Imports a PDF stream into rGraphic as a GDIMetaFile.
+VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Bitmap &rBitmap,
+ css::uno::Sequence<sal_Int8> &rPdfFata,
+ sal_uInt64 nPos = STREAM_SEEK_TO_BEGIN,
+ sal_uInt64 nSize = STREAM_SEEK_TO_END);
VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Graphic& rGraphic);
}
diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx
index 776ef710eee7..062f5ee3701d 100644
--- a/vcl/source/filter/graphicfilter.cxx
+++ b/vcl/source/filter/graphicfilter.cxx
@@ -44,7 +44,7 @@
#include <vcl/wmf.hxx>
#include <vcl/settings.hxx>
#include "igif/gifread.hxx"
-#include "ipdf/pdfread.hxx"
+#include <pdfread.hxx>
#include "jpeg/jpeg.hxx"
#include "ixbm/xbmread.hxx"
#include "ixpm/xpmread.hxx"
diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx
index 254e2adf1cd8..59a7b1f80469 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -7,7 +7,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-#include "pdfread.hxx"
+#include <pdfread.hxx>
#include <config_features.h>
@@ -56,7 +56,8 @@ double pointToPixel(double fPoint)
}
/// Does PDF to bitmap conversion using pdfium.
-bool generatePreview(SvStream& rStream, Graphic& rGraphic)
+bool generatePreview(SvStream& rStream, Bitmap& rBitmap,
+ sal_uInt64 nPos, sal_uInt64 nSize)
{
FPDF_LIBRARY_CONFIG aConfig;
aConfig.version = 2;
@@ -67,7 +68,8 @@ bool generatePreview(SvStream& rStream, Graphic& rGraphic)
// Read input into a buffer.
SvMemoryStream aInBuffer;
- aInBuffer.WriteStream(rStream);
+ rStream.Seek(nPos);
+ aInBuffer.WriteStream(rStream, nSize);
// Load the buffer using pdfium.
FPDF_DOCUMENT pPdfDocument = FPDF_LoadMemDocument(aInBuffer.GetData(), aInBuffer.GetSize(), /*password=*/nullptr);
@@ -103,7 +105,7 @@ bool generatePreview(SvStream& rStream, Graphic& rGraphic)
pWriteAccess->CopyScanline(nRow, pPdfLine, ScanlineFormat::N32BitTcBgra, nStride);
}
}
- rGraphic = aBitmap;
+ rBitmap = aBitmap;
FPDFBitmap_Destroy(pPdfBitmap);
FPDF_ClosePage(pPdfPage);
@@ -114,11 +116,14 @@ bool generatePreview(SvStream& rStream, Graphic& rGraphic)
}
/// Decide if PDF data is old enough to be compatible.
-bool isCompatible(SvStream& rInStream)
+bool isCompatible(SvStream& rInStream, sal_uInt64 nPos, sal_uInt64 nSize)
{
+ if (nSize < 8)
+ return false;
+
// %PDF-x.y
sal_uInt8 aFirstBytes[8];
- rInStream.Seek(STREAM_SEEK_TO_BEGIN);
+ rInStream.Seek(nPos);
sal_uLong nRead = rInStream.ReadBytes(aFirstBytes, 8);
if (nRead < 8)
return false;
@@ -133,13 +138,14 @@ bool isCompatible(SvStream& rInStream)
/// Takes care of transparently downgrading the version of the PDF stream in
/// case it's too new for our PDF export.
-bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream)
+bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream,
+ sal_uInt64 nPos, sal_uInt64 nSize)
{
- bool bCompatible = isCompatible(rInStream);
- rInStream.Seek(STREAM_SEEK_TO_BEGIN);
+ bool bCompatible = isCompatible(rInStream, nPos, nSize);
+ rInStream.Seek( nPos );
if (bCompatible)
// Not converting.
- rOutStream.WriteStream(rInStream);
+ rOutStream.WriteStream(rInStream, nSize);
else
{
// Downconvert to PDF-1.4.
@@ -152,7 +158,7 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream)
// Read input into a buffer.
SvMemoryStream aInBuffer;
- aInBuffer.WriteStream(rInStream);
+ aInBuffer.WriteStream(rInStream, nSize);
// Load the buffer using pdfium.
FPDF_DOCUMENT pPdfDocument = FPDF_LoadMemDocument(aInBuffer.GetData(), aInBuffer.GetSize(), /*password=*/nullptr);
@@ -174,18 +180,22 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream)
return rOutStream.good();
}
#else
-bool generatePreview(SvStream& rStream, Graphic& rGraphic)
+bool generatePreview(SvStream& rStream, Bitmap& rBitmap
+ sal_uInt64 nPos, sal_uInt64 nSize)
{
(void)rStream;
- (void)rGraphic;
+ (void)rBitmap;
+ (void)nPos;
+ (void)nSize;
return true;
}
-bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream)
+bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream,
+ sal_uInt64 nPos, sal_uInt64 nSize)
{
- rInStream.Seek(STREAM_SEEK_TO_BEGIN);
- rOutStream.WriteStream(rInStream);
+ rInStream.Seek(nPos);
+ rOutStream.WriteStream(rInStream, nSize);
return rOutStream.good();
}
#endif // HAVE_FEATURE_PDFIUM
@@ -195,26 +205,38 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream)
namespace vcl
{
-bool ImportPDF(SvStream& rStream, Graphic& rGraphic)
+bool ImportPDF(SvStream& rStream, Bitmap &rBitmap,
+ css::uno::Sequence<sal_Int8> &rPdfData,
+ sal_uInt64 nPos, sal_uInt64 nSize)
{
// Get the preview of the first page.
- if (!generatePreview(rStream, rGraphic))
+ if (!generatePreview(rStream, rBitmap, nPos, nSize))
return false;
// Save the original PDF stream for later use.
SvMemoryStream aMemoryStream;
- if (!getCompatibleStream(rStream, aMemoryStream))
+ if (!getCompatibleStream(rStream, aMemoryStream, nPos, nSize))
return false;
aMemoryStream.Seek(STREAM_SEEK_TO_END);
- uno::Sequence<sal_Int8> aPdfData(aMemoryStream.Tell());
+ rPdfData = css::uno::Sequence<sal_Int8>(aMemoryStream.Tell());
aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN);
- aMemoryStream.ReadBytes(aPdfData.getArray(), aPdfData.getLength());
- rGraphic.setPdfData(aPdfData);
+ aMemoryStream.ReadBytes(rPdfData.getArray(), rPdfData.getLength());
return true;
}
+
+bool ImportPDF(SvStream& rStream, Graphic& rGraphic)
+{
+ uno::Sequence<sal_Int8> aPdfData;
+ Bitmap aBitmap;
+ bool bRet = ImportPDF(rStream, aBitmap, aPdfData);
+ rGraphic = aBitmap;
+ rGraphic.setPdfData(aPdfData);
+ return bRet;
+}
+
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
index b0b472c1c8d8..983eb468e238 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -41,6 +41,8 @@
#include <o3tl/make_unique.hxx>
#include <vcl/gdimetafiletools.hxx>
+#include <pdfread.hxx>
+
#define GRAPHIC_MTFTOBMP_MAXEXT 2048
#define GRAPHIC_STREAMBUFSIZE 8192UL
@@ -1574,13 +1576,14 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic )
// Stream in PDF data.
sal_uInt32 nPdfDataLength = 0;
rIStm.ReadUInt32(nPdfDataLength);
+ Bitmap aBitmap;
- if (nPdfDataLength)
+ if (nPdfDataLength && !rIStm.GetError() &&
+ vcl::ImportPDF(rIStm, aBitmap, rImpGraphic.maPdfData,
+ rIStm.Tell(), nPdfDataLength))
{
- uno::Sequence<sal_Int8> aPdfData(nPdfDataLength);
- rIStm.ReadBytes(aPdfData.getArray(), nPdfDataLength);
- if (!rIStm.GetError())
- rImpGraphic.maPdfData = aPdfData;
+ rImpGraphic.maEx = aBitmap;
+ rImpGraphic.meType = GraphicType::Bitmap;
}
}
else
More information about the Libreoffice-commits
mailing list