CMakeLists.txt | 21 ++++----------------- config.h.cmake | 3 --- poppler/Form.cc | 6 +++--- poppler/PDFDoc.cc | 28 ++++++++++++++++++---------- poppler/PSOutputDev.cc | 29 ++++++----------------------- poppler/PSOutputDev.h | 11 +---------- poppler/XRef.cc | 13 ++++++++++--- poppler/XRef.h | 11 +++++++++-- poppler/poppler-config.h.cmake | 5 ----- 9 files changed, 51 insertions(+), 76 deletions(-)
New commits: commit 7d87c7d2c6ca4f814f87329534a17dbf30203313 Author: Sune Vuorela <[email protected]> Date: Tue Jun 27 22:11:29 2023 +0000 Allow for stream compression and compress font streams in forms diff --git a/CMakeLists.txt b/CMakeLists.txt index 74332ed0..768ae268 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,7 +77,6 @@ set(ENABLE_LIBOPENJPEG "openjpeg2" CACHE STRING "Use libopenjpeg for JPX streams set(ENABLE_CMS "lcms2" CACHE STRING "Use color management system. Possible values: lcms2, none. 'none' disables color management system.") set(ENABLE_DCTDECODER "libjpeg" CACHE STRING "Use libjpeg for DCT streams. Possible values: libjpeg, unmaintained, none. will use libjpeg if available or fail if not. 'unmaintained' gives you the internal unmaintained decoder. Use at your own risk. 'none' compiles no DCT decoder at all. Default: libjpeg") option(ENABLE_LIBCURL "Build libcurl based HTTP support." ON) -option(ENABLE_ZLIB "Build with zlib." ON) option(ENABLE_ZLIB_UNCOMPRESS "Use zlib to uncompress flate streams (not totally safe)." OFF) option(USE_FLOAT "Use single precision arithmetic in the Splash backend" OFF) option(BUILD_SHARED_LIBS "Build poppler as a shared library" ON) @@ -285,14 +284,8 @@ if(ENABLE_CPP) set(ICONV_CONST "const") endif() endif() -if(ENABLE_ZLIB) - find_package(ZLIB) - set(ENABLE_ZLIB ${ZLIB_FOUND}) -endif() -if(ENABLE_ZLIB_UNCOMPRESS AND NOT ENABLE_ZLIB) - message("Warning: ENABLE_ZLIB_UNCOMPRESS requires ENABLE_ZLIB") - set(ENABLE_ZLIB_UNCOMPRESS FALSE) -endif() +find_package(ZLIB REQUIRED) + set(WITH_OPENJPEG FALSE) if(ENABLE_LIBOPENJPEG STREQUAL "openjpeg2") find_package(OpenJPEG) @@ -451,6 +444,7 @@ set(poppler_SRCS poppler/FDPDFDocBuilder.cc poppler/FILECacheLoader.cc poppler/FileSpec.cc + poppler/FlateEncoder.cc poppler/FontEncodingTables.cc poppler/Form.cc poppler/FontInfo.cc @@ -521,7 +515,7 @@ set(poppler_SRCS splash/SplashXPath.cc splash/SplashXPathScanner.cc ) -set(poppler_LIBS Freetype::Freetype) +set(poppler_LIBS Freetype::Freetype ZLIB::ZLIB) if(FONTCONFIG_FOUND) set(poppler_LIBS ${poppler_LIBS} Fontconfig::Fontconfig) endif() @@ -532,12 +526,6 @@ if(JPEG_FOUND) ) set(poppler_LIBS ${poppler_LIBS} JPEG::JPEG) endif() -if(ENABLE_ZLIB) - set(poppler_SRCS ${poppler_SRCS} - poppler/FlateEncoder.cc - ) - set(poppler_LIBS ${poppler_LIBS} ZLIB::ZLIB) -endif() if(ENABLE_ZLIB_UNCOMPRESS) set(poppler_SRCS ${poppler_SRCS} poppler/FlateStream.cc @@ -865,7 +853,6 @@ show_end_message_yesno("cpp wrapper" ENABLE_CPP) show_end_message_yesno("use libjpeg" ENABLE_LIBJPEG) show_end_message_yesno("use libpng" ENABLE_LIBPNG) show_end_message_yesno("use libtiff" ENABLE_LIBTIFF) -show_end_message_yesno("use zlib compress" ENABLE_ZLIB) show_end_message_yesno("use zlib uncompress" ENABLE_ZLIB_UNCOMPRESS) show_end_message_yesno("use nss3" ENABLE_NSS3) show_end_message_yesno("use gpg" ENABLE_GPGME) diff --git a/config.h.cmake b/config.h.cmake index 10abff6e..6faa6c12 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -18,9 +18,6 @@ /* Do not hardcode the library location */ #cmakedefine ENABLE_RELOCATABLE 1 -/* Build against zlib. */ -#cmakedefine ENABLE_ZLIB 1 - /* Use zlib instead of builtin zlib decoder to uncompress flate streams. */ #cmakedefine ENABLE_ZLIB_UNCOMPRESS 1 diff --git a/poppler/Form.cc b/poppler/Form.cc index 72898976..54ab05b1 100644 --- a/poppler/Form.cc +++ b/poppler/Form.cc @@ -2872,12 +2872,12 @@ Form::AddFontResult Form::addFontToDefaultResources(const std::string &filepath, } if (isTrueType) { - const Ref fontFile2Ref = xref->addStreamObject(new Dict(xref), dataPtr, fileSize); + const Ref fontFile2Ref = xref->addStreamObject(new Dict(xref), dataPtr, fileSize, StreamCompression::Compress); fontDescriptor->set("FontFile2", Object(fontFile2Ref)); } else { Dict *fontFileStreamDict = new Dict(xref); fontFileStreamDict->set("Subtype", Object(objName, "OpenType")); - const Ref fontFile3Ref = xref->addStreamObject(fontFileStreamDict, dataPtr, fileSize); + const Ref fontFile3Ref = xref->addStreamObject(fontFileStreamDict, dataPtr, fileSize, StreamCompression::Compress); fontDescriptor->set("FontFile3", Object(fontFile3Ref)); } } @@ -2943,7 +2943,7 @@ Form::AddFontResult Form::addFontToDefaultResources(const std::string &filepath, dataPtr[i++] = (unsigned char)(glyph >> 8); dataPtr[i++] = (unsigned char)(glyph & 0xff); } - const Ref cidToGidMapStream = xref->addStreamObject(new Dict(xref), dataPtr, basicMultilingualMaxCode * 2); + const Ref cidToGidMapStream = xref->addStreamObject(new Dict(xref), dataPtr, basicMultilingualMaxCode * 2, StreamCompression::Compress); descendantFont->set("CIDToGIDMap", Object(cidToGidMapStream)); } diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index fc2f1c37..bcdbc5fc 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -99,6 +99,7 @@ #include "PDFDoc.h" #include "Hints.h" #include "UTF.h" +#include "FlateEncoder.h" #include "JSInfo.h" #include "ImageEmbeddingUtils.h" @@ -1400,8 +1401,8 @@ void PDFDoc::writeObject(Object *obj, OutStream *outStr, XRef *xRef, unsigned in // we write the stream unencoded => TODO: write stream encoder // Encrypt stream - EncryptStream *encStream = nullptr; bool removeFilter = true; + bool addEncryptstream = false; if (stream->getKind() == strWeird && fileKey) { Object filter = stream->getDict()->lookup("Filter"); if (!filter.isName("Crypt")) { @@ -1414,22 +1415,30 @@ void PDFDoc::writeObject(Object *obj, OutStream *outStr, XRef *xRef, unsigned in } } if (removeFilter) { - encStream = new EncryptStream(stream, fileKey, encAlgorithm, keyLength, ref); - encStream->setAutoDelete(false); - stream = encStream; + addEncryptstream = true; } } else { - encStream = new EncryptStream(stream, fileKey, encAlgorithm, keyLength, ref); - encStream->setAutoDelete(false); - stream = encStream; + addEncryptstream = true; } } else { removeFilter = false; } } else if (fileKey != nullptr) { // Encrypt stream - encStream = new EncryptStream(stream, fileKey, encAlgorithm, keyLength, ref); + addEncryptstream = true; + } + + std::unique_ptr<EncryptStream> encStream; + std::unique_ptr<Stream> compressStream; + Object filter = stream->getDict()->lookup("Filter"); + if (filter.isName("FlateDecode")) { + compressStream = std::make_unique<FlateEncoder>(stream); + stream = compressStream.get(); + removeFilter = false; + } + if (addEncryptstream) { + encStream = std::make_unique<EncryptStream>(stream, fileKey, encAlgorithm, keyLength, ref); encStream->setAutoDelete(false); - stream = encStream; + stream = encStream.get(); } stream->reset(); @@ -1452,7 +1461,6 @@ void PDFDoc::writeObject(Object *obj, OutStream *outStr, XRef *xRef, unsigned in writeDictionary(stream->getDict(), outStr, xRef, numOffset, fileKey, encAlgorithm, keyLength, ref, alreadyWrittenDicts); writeStream(stream, outStr); - delete encStream; } else if (fileKey != nullptr && stream->getKind() == strFile && static_cast<FileStream *>(stream)->getNeedsEncryptionOnSave()) { EncryptStream *encStream = new EncryptStream(stream, fileKey, encAlgorithm, keyLength, ref); encStream->setAutoDelete(false); diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc index 7b264f57..11832b23 100644 --- a/poppler/PSOutputDev.cc +++ b/poppler/PSOutputDev.cc @@ -69,9 +69,7 @@ #include "Catalog.h" #include "Page.h" #include "Stream.h" -#ifdef ENABLE_ZLIB -# include "FlateEncoder.h" -#endif +#include "FlateEncoder.h" #ifdef ENABLE_ZLIB_UNCOMPRESS # include "FlateStream.h" #endif @@ -2867,12 +2865,9 @@ void PSOutputDev::setupImage(Ref id, Stream *str, bool mask) if (useCompressed) { str = str->getUndecodedStream(); } -#ifdef ENABLE_ZLIB if (useFlate) { str = new FlateEncoder(str); - } else -#endif - if (useLZW) { + } else if (useLZW) { str = new LZWEncoder(str); } else if (useRLE) { str = new RunLengthEncoder(str); @@ -3466,7 +3461,6 @@ bool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/, i isOptimizedGray = false; } str0->reset(); -#ifdef ENABLE_ZLIB if (useFlate) { if (isOptimizedGray && numComps == 4) { str = new FlateEncoder(new CMYKGrayEncoder(str0)); @@ -3477,9 +3471,7 @@ bool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/, i } else { str = new FlateEncoder(str0); } - } else -#endif - if (useLZW) { + } else if (useLZW) { if (isOptimizedGray && numComps == 4) { str = new LZWEncoder(new CMYKGrayEncoder(str0)); numComps = 1; @@ -6171,12 +6163,9 @@ void PSOutputDev::doImageL3(GfxState *state, Object *ref, GfxImageColorMap *colo if (maskUseCompressed) { maskStr = maskStr->getUndecodedStream(); } -#ifdef ENABLE_ZLIB if (maskUseFlate) { maskStr = new FlateEncoder(maskStr); - } else -#endif - if (maskUseLZW) { + } else if (maskUseLZW) { maskStr = new LZWEncoder(maskStr); } else if (maskUseRLE) { maskStr = new RunLengthEncoder(maskStr); @@ -6218,12 +6207,9 @@ void PSOutputDev::doImageL3(GfxState *state, Object *ref, GfxImageColorMap *colo if (inlineImg) { // create an array str2 = new FixedLengthEncoder(str, len); -#ifdef ENABLE_ZLIB if (getEnableFlate()) { str2 = new FlateEncoder(str2); - } else -#endif - if (getEnableLZW()) { + } else if (getEnableLZW()) { str2 = new LZWEncoder(str2); } else { str2 = new RunLengthEncoder(str2); @@ -6450,12 +6436,9 @@ void PSOutputDev::doImageL3(GfxState *state, Object *ref, GfxImageColorMap *colo } // add FlateEncode/LZWEncode/RunLengthEncode and ASCIIHex/85 encode filters -#ifdef ENABLE_ZLIB if (useFlate) { str = new FlateEncoder(str); - } else -#endif - if (useLZW) { + } else if (useLZW) { str = new LZWEncoder(str); } else if (useRLE) { str = new RunLengthEncoder(str); diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h index cf6f1755..a09f3567 100644 --- a/poppler/PSOutputDev.h +++ b/poppler/PSOutputDev.h @@ -329,16 +329,7 @@ public: bool getOptimizeColorSpace() const { return optimizeColorSpace; } bool getPassLevel1CustomColor() const { return passLevel1CustomColor; } bool getEnableLZW() const { return enableLZW; }; - bool getEnableFlate() const -#ifdef ENABLE_ZLIB - { - return enableFlate; - } -#else - { - return false; - } -#endif + bool getEnableFlate() const { return enableFlate; } void setEmbedType1(bool b) { embedType1 = b; } void setEmbedTrueType(bool b) { embedTrueType = b; } void setEmbedCIDPostScript(bool b) { embedCIDPostScript = b; } diff --git a/poppler/XRef.cc b/poppler/XRef.cc index 81845fa4..9e6266ae 100644 --- a/poppler/XRef.cc +++ b/poppler/XRef.cc @@ -1485,17 +1485,24 @@ void XRef::removeIndirectObject(Ref r) setModified(); } -Ref XRef::addStreamObject(Dict *dict, char *buffer, const Goffset bufferSize) +Ref XRef::addStreamObject(Dict *dict, char *buffer, const Goffset bufferSize, StreamCompression compression) { dict->add("Length", Object((int)bufferSize)); AutoFreeMemStream *stream = new AutoFreeMemStream(buffer, 0, bufferSize, Object(dict)); stream->setFilterRemovalForbidden(true); + switch (compression) { + case StreamCompression::None:; + break; + case StreamCompression::Compress: + stream->getDict()->add("Filter", Object(objName, "FlateDecode")); + break; + } return addIndirectObject(Object((Stream *)stream)); } -Ref XRef::addStreamObject(Dict *dict, uint8_t *buffer, const Goffset bufferSize) +Ref XRef::addStreamObject(Dict *dict, uint8_t *buffer, const Goffset bufferSize, StreamCompression compression) { - return addStreamObject(dict, (char *)buffer, bufferSize); + return addStreamObject(dict, (char *)buffer, bufferSize, compression); } void XRef::writeXRef(XRef::XRefWriter *writer, bool writeAllEntries) diff --git a/poppler/XRef.h b/poppler/XRef.h index e2b2ca8f..5c9877d0 100644 --- a/poppler/XRef.h +++ b/poppler/XRef.h @@ -97,6 +97,13 @@ struct XRefEntry } }; +// How to compress the a added stream +enum class StreamCompression +{ + None, /* No compression */ + Compress, /* Compresses the stream */ +}; + class POPPLER_PRIVATE_EXPORT XRef { public: @@ -213,8 +220,8 @@ public: // The function takes ownership over dict and buffer. // The buffer should be created using gmalloc(). // Returns ref to a new object. - Ref addStreamObject(Dict *dict, char *buffer, const Goffset bufferSize); - Ref addStreamObject(Dict *dict, uint8_t *buffer, const Goffset bufferSize); + Ref addStreamObject(Dict *dict, char *buffer, const Goffset bufferSize, StreamCompression compression = StreamCompression::None); + Ref addStreamObject(Dict *dict, uint8_t *buffer, const Goffset bufferSize, StreamCompression compression = StreamCompression::None); // Output XRef table to stream void writeTableToFile(OutStream *outStr, bool writeAllEntries); diff --git a/poppler/poppler-config.h.cmake b/poppler/poppler-config.h.cmake index f1427d55..598ba5a8 100644 --- a/poppler/poppler-config.h.cmake +++ b/poppler/poppler-config.h.cmake @@ -74,11 +74,6 @@ #cmakedefine ENABLE_LIBPNG 1 #endif -/* Use zlib instead of builtin zlib decoder. */ -#ifndef ENABLE_ZLIB -#cmakedefine ENABLE_ZLIB 1 -#endif - /* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'. */ #ifndef HAVE_DIRENT_H
