vcl/qa/cppunit/pdfexport/pdfexport.cxx | 53 +++++++++++++++++++++++++++++++++ vcl/source/gdi/pdfobjectcopier.cxx | 8 ++++ 2 files changed, 61 insertions(+)
New commits: commit f5ad4f9dfac27d5675fa5c397f66b8cc45cc31a1 Author: Dennis Francis <dennis.fran...@collabora.com> AuthorDate: Thu Dec 1 11:28:49 2022 +0530 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Dec 16 13:43:01 2022 +0000 vcl: /Filter [/FlatDecode] not properly read Change-Id: I156e153ae1a123cf9cf54eb23e6d3abe8962f677 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143560 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index b6b6ba7f7fc0..0e5a5b621950 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -3386,6 +3386,59 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testRexportRefToKids) #endif } +CPPUNIT_TEST_FIXTURE(PdfExportTest, testRexportFilterSingletonArray) +{ +// setenv only works on unix based systems +#ifndef _WIN32 + // We need to enable PDFium import (and make sure to disable after the test) + bool bResetEnvVar = false; + if (getenv("LO_IMPORT_USE_PDFIUM") == nullptr) + { + bResetEnvVar = true; + setenv("LO_IMPORT_USE_PDFIUM", "1", false); + } + comphelper::ScopeGuard aPDFiumEnvVarGuard([&]() { + if (bResetEnvVar) + unsetenv("LO_IMPORT_USE_PDFIUM"); + }); + + // Load the PDF and save as PDF + vcl::filter::PDFDocument aDocument; + load(u"ref-to-kids.pdf", aDocument); + + std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages(); + CPPUNIT_ASSERT_EQUAL(size_t(5), aPages.size()); + + // Directly go to the inner XObject Im5 that contains the rectangle drawings. + auto pInnerIm = aDocument.LookupObject(5); + CPPUNIT_ASSERT(pInnerIm); + + auto pFilter = dynamic_cast<vcl::filter::PDFNameElement*>(pInnerIm->Lookup("Filter")); + CPPUNIT_ASSERT(pFilter); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Filter must be FlateDecode", OString("FlateDecode"), + pFilter->GetValue()); + + vcl::filter::PDFStreamElement* pStream = pInnerIm->GetStream(); + CPPUNIT_ASSERT(pStream); + SvMemoryStream& rObjectStream = pStream->GetMemory(); + // Uncompress it. + SvMemoryStream aUncompressed; + ZCodec aZCodec; + aZCodec.BeginCompression(); + rObjectStream.Seek(0); + aZCodec.Decompress(rObjectStream, aUncompressed); + CPPUNIT_ASSERT(aZCodec.EndCompression()); + + // Without the fix, the stream is doubly compressed, + // hence one decompression will not yield the "re" expressions. + auto pStart = static_cast<const char*>(aUncompressed.GetData()); + const char* pEnd = pStart + aUncompressed.GetSize(); + OString aImage = "100 0 30 50 re B*\n70 67 50 30 re B*\n"; + auto it = std::search(pStart, pEnd, aImage.getStr(), aImage.getStr() + aImage.getLength()); + CPPUNIT_ASSERT(it != pEnd); +#endif +} + } // end anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/vcl/source/gdi/pdfobjectcopier.cxx b/vcl/source/gdi/pdfobjectcopier.cxx index 93b7b4989710..999be92bd752 100644 --- a/vcl/source/gdi/pdfobjectcopier.cxx +++ b/vcl/source/gdi/pdfobjectcopier.cxx @@ -283,6 +283,14 @@ sal_Int32 PDFObjectCopier::copyPageStreams(std::vector<filter::PDFObjectElement* SvMemoryStream& rPageStream = pPageStream->GetMemory(); auto pFilter = dynamic_cast<filter::PDFNameElement*>(pContent->Lookup("Filter")); + auto pFilterArray = dynamic_cast<filter::PDFArrayElement*>(pContent->Lookup("Filter")); + if (!pFilter && pFilterArray) + { + auto& aElements = pFilterArray->GetElements(); + if (!aElements.empty()) + pFilter = dynamic_cast<filter::PDFNameElement*>(aElements[0]); + } + if (pFilter) { if (pFilter->GetValue() != "FlateDecode")