commit ad58a4083bcb5e2db1c2c6599103ba7dc5b78fff Author: William Bader Date: Sun Feb 21 06:01:20 2016 +0100 Add support for Flate compression in Level 3 PostScript output. The changes to the build variables are from Adrian Johnson's DeflateStream patches at https://bugs.freedesktop.org/attachment.cgi?id=89776 --- CMakeLists.txt | 17 ++++++++++++----- config.h.cmake | 5 ++++- configure.ac | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------- poppler/FlateEncoder.cc | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ poppler/FlateEncoder.h | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ poppler/Makefile.am | 13 +++++++++++-- poppler/PSOutputDev.cc | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------- poppler/PSOutputDev.h | 10 +++++++++- poppler/Stream.cc | 4 ++-- poppler/Stream.h | 2 +- poppler/poppler-config.h.in | 6 +++--- 11 files changed, 403 insertions(+), 92 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d30fa4b..109221f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,7 +38,8 @@ option(ENABLE_CPP "Compile poppler cpp wrapper." ON) set(ENABLE_LIBOPENJPEG "auto" CACHE STRING "Use libopenjpeg for JPX streams. Possible values: auto, openjpeg1, openjpeg2. 'auto' prefers openjpeg1 over openjpeg2 if both are available. Unset to not use openjpeg.") set(ENABLE_CMS "auto" CACHE STRING "Use color management system. Possible values: auto, lcms1, lcms2. 'auto' prefers lcms2 over lcms1 if both are available. Unset to disable color management system.") option(ENABLE_LIBCURL "Build libcurl based HTTP support." OFF) -option(ENABLE_ZLIB "Build with zlib (not totally safe)." OFF) +option(ENABLE_ZLIB "Build with zlib." ON) +option(ENABLE_ZLIB_UNCOMPRESS "Use zlib to uncompress flate streams (not totally safe)." OFF) option(SPLASH_CMYK "Include support for CMYK rasterization." OFF) option(USE_FIXEDPOINT "Use fixed point arithmetic in the Splash backend" OFF) option(USE_FLOAT "Use single precision arithmetic in the Splash backend" OFF) @@ -420,10 +421,15 @@ if(JPEG_FOUND) endif(JPEG_FOUND) if(ENABLE_ZLIB) set(poppler_SRCS ${poppler_SRCS} - poppler/FlateStream.cc + poppler/FlateEncoder.cc ) set(poppler_LIBS ${poppler_LIBS} ${ZLIB_LIBRARIES}) endif(ENABLE_ZLIB) +if(ENABLE_ZLIB_UNCOMPRESS) + set(poppler_SRCS ${poppler_SRCS} + poppler/FlateStream.cc + ) +endif(ENABLE_ZLIB_UNCOMPRESS) if(ENABLE_LIBCURL) set(poppler_SRCS ${poppler_SRCS} poppler/CurlCachedFile.cc @@ -716,7 +722,8 @@ show_end_message("use gtk-doc" "not supported with this CMake build system") 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" ENABLE_ZLIB) +show_end_message_yesno("use zlib compress" ENABLE_ZLIB) +show_end_message_yesno("use zlib uncompress" ENABLE_ZLIB_UNCOMPRESS) show_end_message_yesno("use curl" ENABLE_LIBCURL) show_end_message_yesno("use libopenjpeg" WITH_OPENJPEG) if(USE_OPENJPEG1) @@ -747,9 +754,9 @@ if(NOT ENABLE_LIBJPEG) message("Warning: Using libjpeg is recommended. The internal DCT decoder is unmaintained.") endif(NOT ENABLE_LIBJPEG) -if(ENABLE_ZLIB) +if(ENABLE_ZLIB OR ENABLE_ZLIB_COMPRESS) message("Warning: Using zlib is not totally safe") -endif(ENABLE_ZLIB) +endif(ENABLE_ZLIB OR ENABLE_ZLIB_COMPRESS) if(NOT WITH_OPENJPEG) message("Warning: Using libopenjpeg is recommended. The internal JPX decoder is unmaintained.") diff --git a/config.h.cmake b/config.h.cmake index 440a13d..60c5120 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -18,9 +18,12 @@ /* Do not hardcode the library location */ #cmakedefine ENABLE_RELOCATABLE 1 -/* Use zlib instead of builtin zlib decoder. */ +/* Build against zlib. */ #cmakedefine ENABLE_ZLIB 1 +/* Use zlib instead of builtin zlib decoder to uncompress flate streams. */ +#cmakedefine ENABLE_ZLIB_UNCOMPRESS 1 + /* Use cairo for rendering. */ #cmakedefine HAVE_CAIRO 1 diff --git a/configure.ac b/configure.ac index 45575be..879901d 100644 --- a/configure.ac +++ b/configure.ac @@ -344,31 +344,53 @@ fi AC_CHECK_FUNCS(pread64 lseek64) dnl Test for zlib -AC_ARG_ENABLE([zlib], - [AS_HELP_STRING([--enable-zlib],[Build with zlib])], - [],[enable_zlib="no"]) +AC_ARG_ENABLE(zlib, + AC_HELP_STRING([--disable-zlib], + [Don't build against zlib.]), + enable_zlib=$enableval, + enable_zlib="try") + +AC_ARG_ENABLE([zlib_uncompress], + AS_HELP_STRING([--enable-zlib-uncompress], + [Use zlib to uncompress flate streams (not totally safe)]), + enable_zlib_uncompress=$enableval, + enable_zlib_uncompress="no") + if test x$enable_zlib = xyes; then - AC_CHECK_LIB([z], [inflate],, - AC_MSG_ERROR("*** zlib library not found ***")) - AC_CHECK_HEADERS([zlib.h],, - AC_MSG_ERROR("*** zlib headers not found ***")) + AC_CHECK_LIB([z], [inflate],, + AC_MSG_ERROR("*** zlib library not found ***")) + AC_CHECK_HEADERS([zlib.h],, + AC_MSG_ERROR("*** zlib headers not found ***")) elif test x$enable_zlib = xtry; then - AC_CHECK_LIB([z], [inflate], - [enable_zlib="yes"], - [enable_zlib="no"]) - AC_CHECK_HEADERS([zlib.h],, - [enable_zlib="no"]) + AC_CHECK_LIB([z], [inflate], + [enable_zlib="yes"], + [enable_zlib="no"]) + AC_CHECK_HEADERS([zlib.h],, + [enable_zlib="no"]) fi if test x$enable_zlib = xyes; then - ZLIB_LIBS="-lz" - AC_SUBST(ZLIB_LIBS) - AC_DEFINE(ENABLE_ZLIB) + ZLIB_LIBS="-lz" + AC_SUBST(ZLIB_LIBS) + AC_DEFINE(ENABLE_ZLIB, 1, [Build against zlib.]) + + if test x$enable_zlib_uncompress = xyes; then + AC_DEFINE(ENABLE_ZLIB_UNCOMPRESS, 1, + [Use zlib instead of builtin zlib decoder to uncompress flate streams.]) + fi +else + if test x$enable_zlib_uncompress = xyes; then + echo " Warning: --enable-zlib-uncompress is incompatible with --disable-zlib." + fi + enable_zlib_uncompress="no" fi AM_CONDITIONAL(BUILD_ZLIB, test x$enable_zlib = xyes) AH_TEMPLATE([ENABLE_ZLIB], - [Use zlib instead of builtin zlib decoder.]) + [Build against zlib.]) +AM_CONDITIONAL(BUILD_ZLIB_UNCOMPRESS, test x$enable_zlib_uncompress = xyes) +AH_TEMPLATE([ENABLE_ZLIB_UNCOMPRESS], + [Use zlib instead of builtin zlib decoder to uncompress flate streams.]) dnl Test for libcurl AC_ARG_ENABLE(libcurl, @@ -989,24 +1011,25 @@ poppler-cpp-uninstalled.pc]) echo "" echo "Building poppler with support for:" -echo " font configuration: $with_font_configuration" -echo " splash output: $enable_splash_output" +echo " font configuration: $with_font_configuration" +echo " splash output: $enable_splash_output" if test x$enable_cmyk = xyes;then echo " with CMYK support" fi -echo " cairo output: $use_cairo" -echo " qt4 wrapper: $enable_poppler_qt4" -echo " qt5 wrapper: $enable_poppler_qt5" -echo " glib wrapper: $use_glib" -echo " introspection: $found_introspection" -echo " cpp wrapper: $enable_poppler_cpp" -echo " use gtk-doc: $enable_gtk_doc" -echo " use libjpeg: $enable_libjpeg" -echo " use libpng: $enable_libpng" -echo " use libtiff: $enable_libtiff" -echo " use zlib: $enable_zlib" -echo " use libcurl: $enable_libcurl" -echo " use libopenjpeg: $enable_libopenjpeg" +echo " cairo output: $use_cairo" +echo " qt4 wrapper: $enable_poppler_qt4" +echo " qt5 wrapper: $enable_poppler_qt5" +echo " glib wrapper: $use_glib" +echo " introspection: $found_introspection" +echo " cpp wrapper: $enable_poppler_cpp" +echo " use gtk-doc: $enable_gtk_doc" +echo " use libjpeg: $enable_libjpeg" +echo " use libpng: $enable_libpng" +echo " use libtiff: $enable_libtiff" +echo " use zlib compress: $enable_zlib" +echo " use zlib uncompress: $enable_zlib_uncompress" +echo " use libcurl: $enable_libcurl" +echo " use libopenjpeg: $enable_libopenjpeg" if test x$enable_libopenjpeg = xyes;then if test x$openjpeg1 = xyes;then echo " with openjpeg1" @@ -1014,7 +1037,7 @@ if test x$enable_libopenjpeg = xyes;then echo " with openjpeg2" fi fi -echo " use cms: $enable_cms" +echo " use cms: $enable_cms" if test x$enable_cms = xyes;then if test x$lcms1 = xyes;then echo " with lcms1" @@ -1023,10 +1046,10 @@ if test x$enable_cms = xyes;then fi fi if test x$enable_build_type != xno;then - echo " build type: $enable_build_type" + echo " build type: $enable_build_type" fi -echo " command line utils: $enable_utils" -echo " test data dir: $TESTDATADIR" +echo " command line utils: $enable_utils" +echo " test data dir: $TESTDATADIR" echo "" if test x$enable_splash_output = xno -a x$enable_cairo_output = xno; then @@ -1041,8 +1064,8 @@ if test x$enable_libjpeg != xyes; then echo " Warning: Using libjpeg is recommended. The internal DCT decoder is unmaintained." fi -if test x$enable_zlib != xno; then - echo " Warning: Using zlib is not totally safe" +if test x$enable_zlib_uncompress != xno; then + echo " Warning: Using zlib for decompression is not totally safe" fi if test x$enable_libopenjpeg != xyes; then diff --git a/poppler/FlateEncoder.cc b/poppler/FlateEncoder.cc new file mode 100644 index 0000000..74eb5ea --- /dev/null +++ b/poppler/FlateEncoder.cc @@ -0,0 +1,142 @@ +//======================================================================== +// +// FlateEncoder.cc +// +// Copyright (C) 2016, William Bader +// +// This file is under the GPLv2 or later license +// +//======================================================================== + +#include "FlateEncoder.h" + +//------------------------------------------------------------------------ +// FlateEncoder +//------------------------------------------------------------------------ + +FlateEncoder::FlateEncoder(Stream *strA): + FilterStream(strA) +{ + int zlib_status; + + outBufPtr = outBufEnd = outBuf; + inBufEof = outBufEof = gFalse; + + zlib_stream.zalloc = Z_NULL; + zlib_stream.zfree = Z_NULL; + zlib_stream.opaque = Z_NULL; + + zlib_status = deflateInit(&zlib_stream, Z_DEFAULT_COMPRESSION); + + if (zlib_status != Z_OK) { + inBufEof = outBufEof = gTrue; + error(errInternal, -1, "Internal: deflateInit() failed in FlateEncoder::FlateEncoder()"); + } + + zlib_stream.next_out = outBufEnd; + zlib_stream.avail_out = 1; /* anything but 0 to trigger a read */ +} + +FlateEncoder::~FlateEncoder() { + deflateEnd(&zlib_stream); + if (str->isEncoder()) { + delete str; + } +} + +void FlateEncoder::reset() { + int zlib_status; + + str->reset(); + + outBufPtr = outBufEnd = outBuf; + inBufEof = outBufEof = gFalse; + + deflateEnd(&zlib_stream); + + zlib_status = deflateInit(&zlib_stream, Z_DEFAULT_COMPRESSION); + + if (zlib_status != Z_OK) { + inBufEof = outBufEof = gTrue; + error(errInternal, -1, "Internal: deflateInit() failed in FlateEncoder::reset()"); + } + + zlib_stream.next_out = outBufEnd; + zlib_stream.avail_out = 1; /* anything but 0 to trigger a read */ +} + +GBool FlateEncoder::fillBuf() { + int n; + unsigned int starting_avail_out; + int zlib_status; + + /* If the output is done, don't try to read more. */ + + if (outBufEof) { + return gFalse; + } + + /* The output buffer should be empty. */ + /* If it is not empty, push any processed data to the start. */ + + if (outBufPtr > outBuf && outBufPtr < outBufEnd) { + n = outBufEnd - outBufPtr; + memmove(outBuf, outBufPtr, n); + outBufEnd = &outBuf[n]; + } else { + outBufEnd = outBuf; + } + outBufPtr = outBuf; + + /* Keep feeding zlib until we get output. */ + /* zlib might consume a few input buffers */ + /* before it starts producing output. */ + + do { + + /* avail_out > 0 means that zlib has depleted its input */ + /* and needs a new chunk of input in order to generate */ + /* more output. */ + + if (zlib_stream.avail_out != 0) { + + /* Fill the input buffer */ + + n = (inBufEof? 0: str->doGetChars(inBufSize, inBuf)); + + if (n == 0) { + inBufEof = gTrue; + } + + zlib_stream.next_in = inBuf; + zlib_stream.avail_in = n; + } + + /* Ask zlib for output. */ + + zlib_stream.next_out = outBufEnd; + starting_avail_out = &outBuf[ outBufSize ] - outBufEnd; + zlib_stream.avail_out = starting_avail_out; + + zlib_status = deflate(&zlib_stream, (inBufEof? Z_FINISH: Z_NO_FLUSH)); + + if (zlib_status == Z_STREAM_ERROR || + zlib_stream.avail_out < 0 || + zlib_stream.avail_out > starting_avail_out) { + /* Unrecoverable error */ + inBufEof = outBufEof = gTrue; + error(errInternal, -1, "Internal: deflate() failed in FlateEncoder::fillBuf()"); + return gFalse; + } + + } while (zlib_stream.avail_out == outBufSize && !inBufEof); + + outBufEnd = &outBuf[ outBufSize ] - zlib_stream.avail_out; + + if (inBufEof && zlib_stream.avail_out != 0) { + outBufEof = gTrue; + } + + return outBufPtr < outBufEnd; +} + diff --git a/poppler/FlateEncoder.h b/poppler/FlateEncoder.h new file mode 100644 index 0000000..845fdc1 --- /dev/null +++ b/poppler/FlateEncoder.h @@ -0,0 +1,77 @@ +//======================================================================== +// +// FlateEncoder.h +// +// Copyright (C) 2016, William Bader +// +// This file is under the GPLv2 or later license +// +//======================================================================== + +#ifndef FLATEENCODE_H +#define FLATEENCODE_H + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include "poppler-config.h" +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include "goo/gmem.h" +#include "goo/gfile.h" +#include "Error.h" +#include "Object.h" +#include "Decrypt.h" + +#include "Stream.h" + +extern "C" { +#include +} + +//------------------------------------------------------------------------ +// FlateEncoder +//------------------------------------------------------------------------ + +class FlateEncoder: public FilterStream { +public: + + FlateEncoder(Stream *strA); + virtual ~FlateEncoder(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual int getChar() + { return (outBufPtr >= outBufEnd && !fillBuf()) ? EOF : (*outBufPtr++ & 0xff); } + virtual int lookChar() + { return (outBufPtr >= outBufEnd && !fillBuf()) ? EOF : (*outBufPtr & 0xff); } + virtual GooString *getPSFilter(int psLevel, const char *indent) { return NULL; } + virtual GBool isBinary(GBool last = gTrue) { return gTrue; } + virtual GBool isEncoder() { return gTrue; } + +private: + + static const int inBufSize = 16384; + static const int outBufSize = inBufSize; + Guchar inBuf[ inBufSize ]; + Guchar outBuf[ outBufSize ]; + Guchar *outBufPtr; + Guchar *outBufEnd; + GBool inBufEof; + GBool outBufEof; + z_stream zlib_stream; + + GBool fillBuf(); +}; + +#endif diff --git a/poppler/Makefile.am b/poppler/Makefile.am index 79b6000..90340b8 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -82,14 +82,22 @@ endif if BUILD_ZLIB zlib_sources = \ - FlateStream.h \ - FlateStream.cc + FlateEncoder.h \ + FlateEncoder.cc zlib_libs = \ $(ZLIB_LIBS) endif +if BUILD_ZLIB_UNCOMPRESS + +zlib_uncompress_sources = \ + FlateStream.h \ + FlateStream.cc + +endif + if BUILD_LIBCURL libcurl_libs = \ @@ -200,6 +208,7 @@ libpoppler_la_SOURCES = \ $(splash_sources) \ $(libjpeg_sources) \ $(zlib_sources) \ + $(zlib_uncompress_sources) \ $(libjpeg2000_sources) \ $(curl_sources) \ Annot.cc \ diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc index 128233f..d5f706d 100644 --- a/poppler/PSOutputDev.cc +++ b/poppler/PSOutputDev.cc @@ -23,7 +23,7 @@ // Copyright (C) 2009-2013 Thomas Freitag // Copyright (C) 2009 Till Kamppeter // Copyright (C) 2009 Carlos Garcia Campos -// Copyright (C) 2009, 2011, 2012, 2014, 2015 William Bader +// Copyright (C) 2009, 2011, 2012, 2014-2016 William Bader // Copyright (C) 2009 Kovid Goyal // Copyright (C) 2009-2011, 2013-2015 Adrian Johnson // Copyright (C) 2012, 2014 Fabio D'Urso @@ -65,6 +65,12 @@ #include "Catalog.h" #include "Page.h" #include "Stream.h" +#if ENABLE_ZLIB +# include "FlateEncoder.h" +#endif +#if ENABLE_ZLIB_UNCOMPRESS +# include "FlateStream.h" +#endif #include "Annot.h" #include "XRef.h" #include "PreScanOutputDev.h" @@ -1244,6 +1250,7 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA, useASCIIHex = gFalse; useBinary = gFalse; enableLZW = gTrue; + enableFlate = gTrue; rasterMono = gFalse; rasterResolution = 300; uncompressPreloadedImages = gFalse; @@ -2954,7 +2961,7 @@ void PSOutputDev::setupImages(Dict *resDict) { } void PSOutputDev::setupImage(Ref id, Stream *str, GBool mask) { - GBool useLZW, useRLE, useCompressed, doUseASCIIHex; + GBool useFlate, useLZW, useRLE, useCompressed, doUseASCIIHex; GooString *s; int c; int size, line, col, i; @@ -2963,29 +2970,29 @@ void PSOutputDev::setupImage(Ref id, Stream *str, GBool mask) { // filters //~ this does not correctly handle the DeviceN color space //~ -- need to use DeviceNRecoder + + useFlate = useLZW = useRLE = gFalse; + useCompressed = gFalse; + doUseASCIIHex = gFalse; + if (level < psLevel2) { - useLZW = useRLE = gFalse; - useCompressed = gFalse; doUseASCIIHex = gTrue; } else { if (uncompressPreloadedImages) { - useLZW = useRLE = gFalse; - useCompressed = gFalse; + /* nothing to do */; } else { s = str->getPSFilter(level < psLevel3 ? 2 : 3, ""); if (s) { - useLZW = useRLE = gFalse; useCompressed = gTrue; delete s; } else { - if (getEnableLZW()) { + if (level >= psLevel3 && getEnableFlate()) { + useFlate = gTrue; + } else if (getEnableLZW()) { useLZW = gTrue; - useRLE = gFalse; } else { useRLE = gTrue; - useLZW = gFalse; } - useCompressed = gFalse; } } doUseASCIIHex = useASCIIHex; @@ -2993,6 +3000,11 @@ void PSOutputDev::setupImage(Ref id, Stream *str, GBool mask) { if (useCompressed) { str = str->getUndecodedStream(); } +#if ENABLE_ZLIB + if (useFlate) { + str = new FlateEncoder(str); + } else +#endif if (useLZW) { str = new LZWEncoder(str); } else if (useRLE) { @@ -3240,7 +3252,7 @@ GBool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/, PreScanOutputDev *scan; GBool rasterize; #if HAVE_SPLASH - GBool useLZW; + GBool useFlate, useLZW; SplashOutputDev *splashOut; SplashColor paperColor; PDFRectangle box; @@ -3280,6 +3292,7 @@ GBool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/, #if HAVE_SPLASH // get the rasterization parameters + useFlate = getEnableFlate() && level >= psLevel3; useLZW = getEnableLZW(); // start the PS page page->makeBox(rasterResolution, rasterResolution, rotateA, useMediaBox, gFalse, @@ -3591,6 +3604,19 @@ GBool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/, isGray = gFalse; } str0->reset(); +#if ENABLE_ZLIB + if (useFlate) { + if (isGray && numComps == 4) { + str = new FlateEncoder(new CMYKGrayEncoder(str0)); + numComps = 1; + } else if (isGray && numComps == 3) { + str = new FlateEncoder(new RGBGrayEncoder(str0)); + numComps = 1; + } else { + str = new FlateEncoder(str0); + } + } else +#endif if (useLZW) { if (isGray && numComps == 4) { str = new LZWEncoder(new CMYKGrayEncoder(str0)); @@ -3639,7 +3665,9 @@ GBool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/, } else { writePS(" /ASCII85Decode filter\n"); } - if (useLZW) { + if (useFlate) { + writePS(" /FlateDecode filter\n"); + } else if (useLZW) { writePS(" /LZWDecode filter\n"); } else { writePS(" /RunLengthDecode filter\n"); @@ -6150,8 +6178,8 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap, Stream *str2; GooString *s; int n, numComps; - GBool useLZW, useRLE, useASCII, useCompressed; - GBool maskUseLZW, maskUseRLE, maskUseASCII, maskUseCompressed; + GBool useFlate, useLZW, useRLE, useASCII, useCompressed; + GBool maskUseFlate, maskUseLZW, maskUseRLE, maskUseASCII, maskUseCompressed; GooString *maskFilters; GfxSeparationColorSpace *sepCS; GfxColor color; @@ -6159,8 +6187,8 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap, int c; int col, i; - useLZW = useRLE = useASCII = useCompressed = gFalse; // make gcc happy - maskUseLZW = maskUseRLE = maskUseASCII = maskUseCompressed = gFalse; // make gcc happy + useFlate = useLZW = useRLE = useASCII = useCompressed = gFalse; + maskUseFlate = maskUseLZW = maskUseRLE = maskUseASCII = maskUseCompressed = gFalse; maskFilters = NULL; // make gcc happy // explicit masking @@ -6170,23 +6198,18 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap, if ((mode == psModeForm || inType3Char || preloadImagesForms) && uncompressPreloadedImages) { s = NULL; - maskUseLZW = maskUseRLE = gFalse; - maskUseCompressed = gFalse; - maskUseASCII = gFalse; } else { s = maskStr->getPSFilter(3, " "); if (!s) { - if (getEnableLZW()) { + if (getEnableFlate()) { + maskUseFlate = gTrue; + } else if (getEnableLZW()) { maskUseLZW = gTrue; - maskUseRLE = gFalse; } else { maskUseRLE = gTrue; - maskUseLZW = gFalse; } maskUseASCII = !(mode == psModeForm || inType3Char || preloadImagesForms); - maskUseCompressed = gFalse; } else { - maskUseLZW = maskUseRLE = gFalse; maskUseASCII = maskStr->isBinary() && !(mode == psModeForm || inType3Char || preloadImagesForms); maskUseCompressed = gTrue; @@ -6197,7 +6220,9 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap, maskFilters->appendf(" /ASCII{0:s}Decode filter\n", useASCIIHex ? "Hex" : "85"); } - if (maskUseLZW) { + if (maskUseFlate) { + maskFilters->append(" /FlateDecode filter\n"); + } else if (maskUseLZW) { maskFilters->append(" /LZWDecode filter\n"); } else if (maskUseRLE) { maskFilters->append(" /RunLengthDecode filter\n"); @@ -6216,10 +6241,15 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap, writePS(maskFilters->getCString()); writePS("pdfMask\n"); - // add LZWEncode/RunLengthEncode and ASCIIHex/85 encode filters + // add FlateEncode/LZWEncode/RunLengthEncode and ASCIIHex/85 encode filters if (maskUseCompressed) { maskStr = maskStr->getUndecodedStream(); } +#if ENABLE_ZLIB + if (maskUseFlate) { + maskStr = new FlateEncoder(maskStr); + } else +#endif if (maskUseLZW) { maskStr = new LZWEncoder(maskStr); } else if (maskUseRLE) { @@ -6243,7 +6273,7 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap, writePS("%-EOD-\n"); // delete encoders - if (maskUseLZW || maskUseRLE || maskUseASCII) { + if (maskUseFlate || maskUseLZW || maskUseRLE || maskUseASCII) { delete maskStr; } } @@ -6260,6 +6290,11 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap, if (inlineImg) { // create an array str2 = new FixedLengthEncoder(str, len); +#if ENABLE_ZLIB + if (getEnableFlate()) { + str2 = new FlateEncoder(str2); + } else +#endif if (getEnableLZW()) { str2 = new LZWEncoder(str2); } else { @@ -6307,7 +6342,7 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap, } } while (c != (useASCIIHex ? '>' : '~') && c != EOF); writePS((char *)(useASCIIHex ? ">\n" : "~>\n")); - // add an extra entry because the LZWDecode/RunLengthDecode filter may + // add an extra entry because the FlateEncode/LZWDecode/RunLengthDecode filter may // read past the end writePS("<>]\n"); writePS("0\n"); @@ -6390,28 +6425,28 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap, } // filters + + useFlate = useLZW = useRLE = gFalse; + useCompressed = gFalse; + useASCII = gFalse; + if ((mode == psModeForm || inType3Char || preloadImagesForms) && uncompressPreloadedImages) { s = NULL; - useLZW = useRLE = gFalse; - useCompressed = gFalse; - useASCII = gFalse; } else { s = str->getPSFilter(level < psLevel2 ? 1 : level < psLevel3 ? 2 : 3, " "); if ((colorMap && colorMap->getColorSpace()->getMode() == csDeviceN) || inlineImg || !s) { - if (getEnableLZW()) { + if (getEnableFlate()) { + useFlate = gTrue; + } else if (getEnableLZW()) { useLZW = gTrue; - useRLE = gFalse; } else { useRLE = gTrue; - useLZW = gFalse; } useASCII = !(mode == psModeForm || inType3Char || preloadImagesForms); - useCompressed = gFalse; } else { - useLZW = useRLE = gFalse; useASCII = str->isBinary() && !(mode == psModeForm || inType3Char || preloadImagesForms); useCompressed = gTrue; @@ -6421,7 +6456,9 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap, writePSFmt(" /ASCII{0:s}Decode filter\n", useASCIIHex ? "Hex" : "85"); } - if (useLZW) { + if (useFlate) { + writePS(" /FlateDecode filter\n"); + } else if (useLZW) { writePS(" /LZWDecode filter\n"); } else if (useRLE) { writePS(" /RunLengthDecode filter\n"); @@ -6499,7 +6536,12 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap, str = str->getUndecodedStream(); } - // add LZWEncode/RunLengthEncode and ASCIIHex/85 encode filters + // add FlateEncode/LZWEncode/RunLengthEncode and ASCIIHex/85 encode filters +#if ENABLE_ZLIB + if (useFlate) { + str = new FlateEncoder(str); + } else +#endif if (useLZW) { str = new LZWEncoder(str); } else if (useRLE) { @@ -6525,7 +6567,7 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap, writePS("%-EOD-\n"); // delete encoders - if (useLZW || useRLE || useASCII || inlineImg) { + if (useFlate || useLZW || useRLE || useASCII || inlineImg) { delete str; } } diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h index bd5b075..3aea223 100644 --- a/poppler/PSOutputDev.h +++ b/poppler/PSOutputDev.h @@ -20,7 +20,7 @@ // Copyright (C) 2009-2013 Thomas Freitag // Copyright (C) 2009 Till Kamppeter // Copyright (C) 2009 Carlos Garcia Campos -// Copyright (C) 2009, 2011, 2015 William Bader +// Copyright (C) 2009, 2011, 2015-2016 William Bader // Copyright (C) 2010 Hib Eris // Copyright (C) 2011, 2014 Adrian Johnson // Copyright (C) 2012 Fabio D'Urso @@ -321,6 +321,12 @@ public: GBool getFontPassthrough() const { return fontPassthrough; } GBool getOptimizeColorSpace() const { return optimizeColorSpace; } GBool getEnableLZW() const { return enableLZW; }; + GBool getEnableFlate() const +#if ENABLE_ZLIB + { return enableFlate; } +#else + { return gFalse; } +#endif void setEmbedType1(GBool b) { embedType1 = b; } void setEmbedTrueType(GBool b) { embedTrueType = b; } void setEmbedCIDPostScript(GBool b) { embedCIDPostScript = b; } @@ -332,6 +338,7 @@ public: void setUseASCIIHex(GBool b) { useASCIIHex = b; } void setUseBinary(GBool b) { useBinary = b; } void setEnableLZW(GBool b) { enableLZW = b; } + void setEnableFlate(GBool b) { enableFlate = b; } private: @@ -535,6 +542,7 @@ private: GBool useASCIIHex; // use ASCIIHex instead of ASCII85? GBool useBinary; // use binary instead of hex GBool enableLZW; // enable LZW compression + GBool enableFlate; // enable Flate compression #if OPI_SUPPORT int opi13Nest; // nesting level of OPI 1.3 objects diff --git a/poppler/Stream.cc b/poppler/Stream.cc index f2ca60b..bbea4fd 100644 --- a/poppler/Stream.cc +++ b/poppler/Stream.cc @@ -70,7 +70,7 @@ #include "DCTStream.h" #endif -#ifdef ENABLE_ZLIB +#ifdef ENABLE_ZLIB_UNCOMPRESS #include "FlateStream.h" #endif @@ -3865,7 +3865,7 @@ GBool DCTStream::isBinary(GBool last) { #endif -#ifndef ENABLE_ZLIB +#ifndef ENABLE_ZLIB_UNCOMPRESS //------------------------------------------------------------------------ // FlateStream //------------------------------------------------------------------------ diff --git a/poppler/Stream.h b/poppler/Stream.h index 84a8cf9..ed6f7dc 100644 --- a/poppler/Stream.h +++ b/poppler/Stream.h @@ -942,7 +942,7 @@ private: #endif -#ifndef ENABLE_ZLIB +#ifndef ENABLE_ZLIB_UNCOMPRESS //------------------------------------------------------------------------ // FlateStream //------------------------------------------------------------------------ diff --git a/poppler/poppler-config.h.in b/poppler/poppler-config.h.in index cb77eb7..79d452f 100644 --- a/poppler/poppler-config.h.in +++ b/poppler/poppler-config.h.in @@ -81,9 +81,9 @@ #undef ENABLE_LIBPNG #endif -/* Use zlib instead of builtin zlib decoder. */ -#ifndef ENABLE_ZLIB -#undef ENABLE_ZLIB +/* Use zlib instead of builtin zlib decoder for uncompressing flate streams. */ +#ifndef ENABLE_ZLIB_UNCOMPRESS +#undef ENABLE_ZLIB_UNCOMPRESS #endif /* Define to 1 if you have the header file, and it defines `DIR'.