vcl/qa/cppunit/pdfexport/pdfexport.cxx | 50 +++++++++++++++++++++++++++++++++ vcl/source/gdi/pdfobjectcopier.cxx | 8 +++++ 2 files changed, 58 insertions(+)
New commits: commit db2757e110c1d99bc6128d80a0c6b9fd63982b89 Author: Dennis Francis <dennis.fran...@collabora.com> AuthorDate: Thu Dec 1 11:28:49 2022 +0530 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Dec 21 07:59:04 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> (cherry picked from commit f5ad4f9dfac27d5675fa5c397f66b8cc45cc31a1) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144435 Tested-by: Jenkins diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index f18077505abd..428f9d5a132a 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -4136,6 +4136,56 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testRexportRefToKids) } } +CPPUNIT_TEST_FIXTURE(PdfExportTest, testRexportFilterSingletonArray) +{ + // 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; + osl_setEnvironment(OUString("LO_IMPORT_USE_PDFIUM").pData, OUString("1").pData); + } + comphelper::ScopeGuard aPDFiumEnvVarGuard([&]() { + if (bResetEnvVar) + osl_clearEnvironment(OUString("LO_IMPORT_USE_PDFIUM").pData); + }); + + // 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); +} + } // 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")