diff options
-rw-r--r-- | include/tools/stream.hxx | 1 | ||||
-rw-r--r-- | tools/source/stream/stream.cxx | 21 | ||||
-rw-r--r-- | vcl/inc/pdfread.hxx (renamed from vcl/source/filter/ipdf/pdfread.hxx) | 4 | ||||
-rw-r--r-- | vcl/source/filter/graphicfilter.cxx | 2 | ||||
-rw-r--r-- | vcl/source/filter/ipdf/pdfread.cxx | 66 | ||||
-rw-r--r-- | vcl/source/gdi/impgraph.cxx | 13 |
6 files changed, 79 insertions, 28 deletions
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 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 |