CMakeLists.txt | 15 +++ config.h.cmake | 3 configure.ac | 32 +++++++ goo/Makefile.am | 2 goo/TiffWriter.cc | 202 +++++++++++++++++++++++++++++++++++++++++++++++++ goo/TiffWriter.h | 53 ++++++++++++ poppler/Makefile.am | 11 ++ splash/SplashBitmap.cc | 18 +++- splash/SplashBitmap.h | 5 - splash/SplashTypes.h | 4 utils/pdftoppm.1 | 6 + utils/pdftoppm.cc | 14 +++ 12 files changed, 358 insertions(+), 7 deletions(-)
New commits: commit 1c7937dbc3c577ffc12cacc8de33d320e2f30ce9 Author: William Bader <[email protected]> Date: Wed Dec 29 14:47:06 2010 +0000 Make pdftoppm be able of writing tif files BUG 32027 diff --git a/CMakeLists.txt b/CMakeLists.txt index b904690..c61b76a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,7 @@ if(WITH_FONTCONFIGURATION_FONTCONFIG) endif(WITH_FONTCONFIGURATION_FONTCONFIG) macro_optional_find_package(JPEG) macro_optional_find_package(PNG) +macro_optional_find_package(TIFF) if(JPEG_FOUND) set(ENABLE_LIBJPEG ${JPEG_FOUND}) endif(JPEG_FOUND) @@ -178,6 +179,10 @@ if(PNG_FOUND) include_directories(${PNG_INCLUDE_DIR}) set(ENABLE_LIBPNG ON) endif(PNG_FOUND) +if(TIFF_FOUND) + include_directories(${TIFF_INCLUDE_DIR}) + set(ENABLE_LIBTIFF ON) +endif(TIFF_FOUND) if(ENABLE_ABIWORD) include_directories(${LIBXML2_INCLUDE_DIR}) add_definitions(${LIBXML2_DEFINITIONS}) @@ -220,6 +225,7 @@ set(poppler_SRCS goo/gmem.cc goo/FixedPoint.cc goo/PNGWriter.cc + goo/TiffWriter.cc goo/JpegWriter.cc goo/ImgWriter.cc goo/gstrtod.cc @@ -360,6 +366,9 @@ endif(WIN32) if(PNG_FOUND) set(poppler_LIBS ${poppler_LIBS} ${PNG_LIBRARIES}) endif(PNG_FOUND) +if(TIFF_FOUND) + set(poppler_LIBS ${poppler_LIBS} ${TIFF_LIBRARIES}) +endif(TIFF_FOUND) if(MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) @@ -464,6 +473,11 @@ if(ENABLE_XPDF_HEADERS) goo/PNGWriter.h DESTINATION include/poppler/goo) endif(PNG_FOUND) + if(TIFF_FOUND) + install(FILES + goo/TiffWriter.h + DESTINATION include/poppler/goo) + endif(TIFF_FOUND) install(FILES fofi/FoFiBase.h fofi/FoFiEncodings.h @@ -587,6 +601,7 @@ show_end_message_yesno("cpp wrapper" ENABLE_CPP) 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 curl" ENABLE_LIBCURL) show_end_message_yesno("use libopenjpeg" LIBOPENJPEG_FOUND) diff --git a/config.h.cmake b/config.h.cmake index 5d27156..71f18a3 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -9,6 +9,9 @@ /* Use libopenjpeg instead of builtin jpeg2000 decoder. */ #cmakedefine ENABLE_LIBOPENJPEG 1 +/* Build against libtiff. */ +#cmakedefine ENABLE_LIBTIFF 1 + /* Build against libpng. */ #cmakedefine ENABLE_LIBPNG 1 diff --git a/configure.ac b/configure.ac index 831452b..347094f 100644 --- a/configure.ac +++ b/configure.ac @@ -173,6 +173,37 @@ AM_CONDITIONAL(BUILD_LIBOPENJPEG, test x$enable_libopenjpeg = xyes) AH_TEMPLATE([ENABLE_LIBOPENJPEG], [Use libopenjpeg instead of builtin jpeg2000 decoder.]) +dnl ##### Test for libtiff +AC_ARG_ENABLE(libtiff, + AC_HELP_STRING([--disable-libtiff], + [Don't build against libtiff.]), + enable_libtiff=$enableval, + enable_libtiff="try") + +if test x$enable_libtiff = xyes; then + AC_CHECK_LIB([tiff], [TIFFOpen],, + AC_MSG_ERROR("*** libtiff library not found ***")) + AC_CHECK_HEADERS([tiffio.h],, + AC_MSG_ERROR("*** libtiff headers not found ***")) +elif test x$enable_libtiff = xtry; then + AC_CHECK_LIB([tiff], [TIFFOpen], + [enable_libtiff="yes"], + [enable_libtiff="no"]) + AC_CHECK_HEADERS([tiffio.h],, + [enable_libtiff="no"]) +fi + +if test x$enable_libtiff = xyes; then + LIBTIFF_LIBS="-ltiff" + AC_SUBST(LIBTIFF_LIBS) + AC_DEFINE(ENABLE_LIBTIFF) +fi + +AM_CONDITIONAL(BUILD_LIBTIFF, test x$enable_libtiff = xyes) +AH_TEMPLATE([ENABLE_LIBTIFF], [Build against libtiff.]) +if test x$enable_libtiff = xyes; then + AC_DEFINE(ENABLE_LIBTIFF, 1, [Build against libtiff.]) +fi dnl ##### Checks for library functions. AC_CHECK_FUNCS(popen mkstemp mkstemps) @@ -686,6 +717,7 @@ 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" diff --git a/goo/Makefile.am b/goo/Makefile.am index de894af..be791ee 100644 --- a/goo/Makefile.am +++ b/goo/Makefile.am @@ -15,6 +15,7 @@ poppler_goo_include_HEADERS = \ FixedPoint.h \ PNGWriter.h \ JpegWriter.h \ + TiffWriter.h \ ImgWriter.h \ GooLikely.h \ gstrtod.h @@ -40,5 +41,6 @@ libgoo_la_SOURCES = \ FixedPoint.cc \ PNGWriter.cc \ JpegWriter.cc \ + TiffWriter.cc \ ImgWriter.cc \ gstrtod.cc diff --git a/goo/TiffWriter.cc b/goo/TiffWriter.cc new file mode 100644 index 0000000..f63b245 --- /dev/null +++ b/goo/TiffWriter.cc @@ -0,0 +1,202 @@ +//======================================================================== +// +// TiffWriter.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright (C) 2010 William Bader <[email protected]> +// +//======================================================================== + +#include "TiffWriter.h" + +#if ENABLE_LIBTIFF + +#include <string.h> + +TiffWriter::~TiffWriter() +{ + // no cleanup needed +} + +TiffWriter::TiffWriter() +{ + f = NULL; + numRows = 0; + curRow = 0; + compressionString = NULL; + splashMode = splashModeRGB8; +} + +// Set the compression type + +void TiffWriter::setCompressionString(const char *compressionStringArg) +{ + compressionString = compressionStringArg; +} + +// Set the bitmap mode + +void TiffWriter::setSplashMode(SplashColorMode splashModeArg) +{ + splashMode = splashModeArg; +} + +// Write a TIFF file. + +bool TiffWriter::init(FILE *openedFile, int width, int height, int hDPI, int vDPI) +{ + unsigned int compression; + uint16 photometric; + uint32 rowsperstrip = (uint32) -1; + int bitspersample; + uint16 samplesperpixel; + const struct compression_name_tag { + const char *compressionName; // name of the compression option from the command line + unsigned int compressionCode; // internal libtiff code + const char *compressionDescription; // descriptive name + } compressionList[] = { + { "none", COMPRESSION_NONE, "no compression" }, + { "ccittrle", COMPRESSION_CCITTRLE, "CCITT modified Huffman RLE" }, + { "ccittfax3", COMPRESSION_CCITTFAX3,"CCITT Group 3 fax encoding" }, + { "ccittt4", COMPRESSION_CCITT_T4, "CCITT T.4 (TIFF 6 name)" }, + { "ccittfax4", COMPRESSION_CCITTFAX4, "CCITT Group 4 fax encoding" }, + { "ccittt6", COMPRESSION_CCITT_T6, "CCITT T.6 (TIFF 6 name)" }, + { "lzw", COMPRESSION_LZW, "Lempel-Ziv & Welch" }, + { "ojpeg", COMPRESSION_OJPEG, "!6.0 JPEG" }, + { "jpeg", COMPRESSION_JPEG, "%JPEG DCT compression" }, + { "next", COMPRESSION_NEXT, "NeXT 2-bit RLE" }, + { "packbits", COMPRESSION_PACKBITS, "Macintosh RLE" }, + { "ccittrlew", COMPRESSION_CCITTRLEW, "CCITT modified Huffman RLE w/ word alignment" }, + { "deflate", COMPRESSION_DEFLATE, "Deflate compression" }, + { "adeflate", COMPRESSION_ADOBE_DEFLATE, "Deflate compression, as recognized by Adobe" }, + { "dcs", COMPRESSION_DCS, "Kodak DCS encoding" }, + { "jbig", COMPRESSION_JBIG, "ISO JBIG" }, + { "jp2000", COMPRESSION_JP2000, "Leadtools JPEG2000" }, + { NULL, 0, NULL } + }; + + // Initialize + + f = NULL; + curRow = 0; + + // Store the number of rows + + numRows = height; + + // Set the compression + + compression = COMPRESSION_NONE; + + if (compressionString == NULL || strcmp(compressionString, "") == 0) { + compression = COMPRESSION_NONE; + } else { + int i; + for (i = 0; compressionList[i].compressionName != NULL; i++) { + if (strcmp(compressionString, compressionList[i].compressionName) == 0) { + compression = compressionList[i].compressionCode; + break; + } + } + if (compressionList[i].compressionName == NULL) { + fprintf(stderr, "TiffWriter: Unknown compression type '%.10s', using 'none'.\n", compressionString); + fprintf(stderr, "Known compression types (the tiff library might not support every type)\n"); + for (i = 0; compressionList[i].compressionName != NULL; i++) { + fprintf(stderr, "%10s %s\n", compressionList[i].compressionName, compressionList[i].compressionDescription); + } + } + } + + // Set bits per sample, samples per pixel, and photometric type from the splash mode + + bitspersample = (splashMode == splashModeMono1? 1: 8); + + switch (splashMode) { + + case splashModeMono1: + case splashModeMono8: + samplesperpixel = 1; + photometric = PHOTOMETRIC_MINISBLACK; + break; + + case splashModeRGB8: + case splashModeBGR8: + samplesperpixel = 3; + photometric = PHOTOMETRIC_RGB; + break; + + default: + fprintf(stderr, "TiffWriter: Mode %d not supported\n", splashMode); + return false; + } + + // Open the file + + if (openedFile == NULL) { + fprintf(stderr, "TiffWriter: No output file given.\n"); + return false; + } + + f = TIFFFdOpen(fileno(openedFile), "-", "w"); + + if (!f) { + return false; + } + + // Set TIFF tags + + TIFFSetField(f, TIFFTAG_IMAGEWIDTH, width); + TIFFSetField(f, TIFFTAG_IMAGELENGTH, height); + TIFFSetField(f, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); + TIFFSetField(f, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel); + TIFFSetField(f, TIFFTAG_BITSPERSAMPLE, bitspersample); + TIFFSetField(f, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(f, TIFFTAG_PHOTOMETRIC, photometric); + TIFFSetField(f, TIFFTAG_COMPRESSION, (uint16) compression); + TIFFSetField(f, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(f, rowsperstrip)); + TIFFSetField(f, TIFFTAG_XRESOLUTION, (double) hDPI); + TIFFSetField(f, TIFFTAG_YRESOLUTION, (double) vDPI); + TIFFSetField(f, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); + + return true; +} + +bool TiffWriter::writePointers(unsigned char **rowPointers, int rowCount) +{ + // Write all rows to the file + + for (int row = 0; row < rowCount; row++) { + if (TIFFWriteScanline(f, rowPointers[row], row, 0) < 0) { + fprintf(stderr, "TiffWriter: Error writing tiff row %d\n", row); + return false; + } + } + + return true; +} + +bool TiffWriter::writeRow(unsigned char **rowData) +{ + // Add a single row + + if (TIFFWriteScanline(f, *rowData, curRow, 0) < 0) { + fprintf(stderr, "TiffWriter: Error writing tiff row %d\n", curRow); + return false; + } + + curRow++; + + return true; +} + +bool TiffWriter::close() +{ + // Close the file + + TIFFClose(f); + + return true; +} + +#endif diff --git a/goo/TiffWriter.h b/goo/TiffWriter.h new file mode 100644 index 0000000..8c9e04a --- /dev/null +++ b/goo/TiffWriter.h @@ -0,0 +1,53 @@ +//======================================================================== +// +// TiffWriter.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright (C) 2010 William Bader <[email protected]> +// +//======================================================================== + +#ifndef TIFFWRITER_H +#define TIFFWRITER_H + +#include <config.h> + +#ifdef ENABLE_LIBTIFF + +#include <sys/types.h> +#include "ImgWriter.h" +#include "splash/SplashTypes.h" + +extern "C" { +#include "tiffio.h" +} + +class TiffWriter : public ImgWriter +{ + public: + TiffWriter(); + ~TiffWriter(); + + void setCompressionString(const char *compressionStringArg); + void setSplashMode(SplashColorMode splashModeArg); + + bool init(FILE *openedFile, int width, int height, int hDPI, int vDPI); + + bool writePointers(unsigned char **rowPointers, int rowCount); + bool writeRow(unsigned char **rowData); + + bool close(); + + private: + TIFF *f; // LibTiff file context + int numRows; // number of rows in the image + int curRow; // number of rows written + const char *compressionString; // compression type + SplashColorMode splashMode; // format of image data + +}; + +#endif + +#endif diff --git a/poppler/Makefile.am b/poppler/Makefile.am index 2e9ee68..ae7317c 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -73,6 +73,15 @@ libpng_includes = \ endif +if BUILD_LIBTIFF + +libtiff_libs = \ + $(LIBTIFF_LIBS) +libtiff_includes = \ + $(LIBTIFF_CFLAGS) + +endif + if BUILD_LIBOPENJPEG libjpeg2000_sources = \ @@ -147,6 +156,7 @@ INCLUDES = \ $(cairo_includes) \ $(arthur_includes) \ $(abiword_includes) \ + $(libtiff_includes) \ $(libpng_includes) \ $(libcurl_includes) \ $(FREETYPE_CFLAGS) \ @@ -165,6 +175,7 @@ libpoppler_la_LIBADD = \ $(top_builddir)/fofi/libfofi.la \ $(cms_libs) \ $(splash_libs) \ + $(libtiff_libs) \ $(libjpeg_libs) \ $(libpng_libs) \ $(zlib_libs) \ diff --git a/splash/SplashBitmap.cc b/splash/SplashBitmap.cc index 51e48d3..7c26e54 100644 --- a/splash/SplashBitmap.cc +++ b/splash/SplashBitmap.cc @@ -18,6 +18,7 @@ // Copyright (C) 2010 Adrian Johnson <[email protected]> // Copyright (C) 2010 Harry Roberts <[email protected]> // Copyright (C) 2010 Christian Feuersänger <[email protected]> +// Copyright (C) 2010 William Bader <[email protected]> // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -39,6 +40,7 @@ #include "poppler/Error.h" #include "goo/JpegWriter.h" #include "goo/PNGWriter.h" +#include "goo/TiffWriter.h" #include "goo/ImgWriter.h" //------------------------------------------------------------------------ @@ -274,7 +276,7 @@ Guchar SplashBitmap::getAlpha(int x, int y) { return alpha[y * width + x]; } -SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, char *fileName, int hDPI, int vDPI) { +SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, char *fileName, int hDPI, int vDPI, const char *compressionString) { FILE *f; SplashError e; @@ -282,13 +284,13 @@ SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, char *fileN return splashErrOpenFile; } - e = writeImgFile(format, f, hDPI, vDPI); + e = writeImgFile(format, f, hDPI, vDPI, compressionString); fclose(f); return e; } -SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, FILE *f, int hDPI, int vDPI) { +SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, FILE *f, int hDPI, int vDPI, const char *compressionString) { ImgWriter *writer; SplashError e; @@ -305,6 +307,16 @@ SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, FILE *f, in break; #endif + #ifdef ENABLE_LIBTIFF + case splashFormatTiff: + writer = new TiffWriter(); + if (writer) { + ((TiffWriter *)writer)->setCompressionString(compressionString); + ((TiffWriter *)writer)->setSplashMode(mode); + } + break; + #endif + default: // Not the greatest error message, but users of this function should // have already checked whether their desired format is compiled in. diff --git a/splash/SplashBitmap.h b/splash/SplashBitmap.h index 1c19421..b276a61 100644 --- a/splash/SplashBitmap.h +++ b/splash/SplashBitmap.h @@ -18,6 +18,7 @@ // Copyright (C) 2010 Adrian Johnson <[email protected]> // Copyright (C) 2010 Harry Roberts <[email protected]> // Copyright (C) 2010 Christian Feuersänger <[email protected]> +// Copyright (C) 2010 William Bader <[email protected]> // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -65,8 +66,8 @@ public: SplashError writePNMFile(char *fileName); SplashError writePNMFile(FILE *f); - SplashError writeImgFile(SplashImageFileFormat format, char *fileName, int hDPI, int vDPI); - SplashError writeImgFile(SplashImageFileFormat format, FILE *f, int hDPI, int vDPI); + SplashError writeImgFile(SplashImageFileFormat format, char *fileName, int hDPI, int vDPI, const char *compressionString = ""); + SplashError writeImgFile(SplashImageFileFormat format, FILE *f, int hDPI, int vDPI, const char *compressionString = ""); SplashError writeImgFile(ImgWriter *writer, FILE *f, int hDPI, int vDPI); void getPixel(int x, int y, SplashColorPtr pixel); diff --git a/splash/SplashTypes.h b/splash/SplashTypes.h index 993dd46..273c32d 100644 --- a/splash/SplashTypes.h +++ b/splash/SplashTypes.h @@ -15,6 +15,7 @@ // Copyright (C) 2008 Tomas Are Haavet <[email protected]> // Copyright (C) 2009 Thomas Freitag <[email protected]> // Copyright (C) 2009 Stefan Thomas <[email protected]> +// Copyright (C) 2010 William Bader <[email protected]> // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -160,7 +161,8 @@ typedef int SplashError; enum SplashImageFileFormat { splashFormatJpeg, - splashFormatPng + splashFormatPng, + splashFormatTiff }; #endif diff --git a/utils/pdftoppm.1 b/utils/pdftoppm.1 index f7af779..66b985c 100644 --- a/utils/pdftoppm.1 +++ b/utils/pdftoppm.1 @@ -86,6 +86,12 @@ Generates a PNG file instead a PPM file. .B \-jpeg Generates a JPEG file instead a PPM file. .TP +.B \-tiff +Generates a TIFF file instead a PPM file. +.TP +.BI \-tiffcompression " none | packbits | jpeg | lzw | deflate" +Specifies the TIFF compression type. This defaults to "none". +.TP .BI \-freetype " yes | no" Enable or disable FreeType (a TrueType / Type 1 font rasterizer). This defaults to "yes". diff --git a/utils/pdftoppm.cc b/utils/pdftoppm.cc index aea65e8..8a7c702 100644 --- a/utils/pdftoppm.cc +++ b/utils/pdftoppm.cc @@ -71,11 +71,13 @@ static GBool mono = gFalse; static GBool gray = gFalse; static GBool png = gFalse; static GBool jpeg = gFalse; +static GBool tiff = gFalse; static char enableFreeTypeStr[16] = ""; static char antialiasStr[16] = ""; static char vectorAntialiasStr[16] = ""; static char ownerPassword[33] = ""; static char userPassword[33] = ""; +static char TiffCompressionStr[16] = ""; static GBool quiet = gFalse; static GBool printVersion = gFalse; static GBool printHelp = gFalse; @@ -130,6 +132,12 @@ static const ArgDesc argDesc[] = { {"-jpeg", argFlag, &jpeg, 0, "generate a JPEG file"}, #endif +#if ENABLE_LIBTIFF + {"-tiff", argFlag, &tiff, 0, + "generate a TIFF file"}, + {"-tiffcompression", argString, TiffCompressionStr, sizeof(TiffCompressionStr), + "set TIFF compression: none, packbits, jpeg, lzw, deflate"}, +#endif #if HAVE_FREETYPE_FREETYPE_H | HAVE_FREETYPE_H {"-freetype", argString, enableFreeTypeStr, sizeof(enableFreeTypeStr), "enable FreeType font rasterizer: yes, no"}, @@ -183,6 +191,8 @@ static void savePageSlice(PDFDoc *doc, bitmap->writeImgFile(splashFormatPng, ppmFile, x_resolution, y_resolution); } else if (jpeg) { bitmap->writeImgFile(splashFormatJpeg, ppmFile, x_resolution, y_resolution); + } else if (tiff) { + bitmap->writeImgFile(splashFormatTiff, ppmFile, x_resolution, y_resolution, TiffCompressionStr); } else { bitmap->writePNMFile(ppmFile); } @@ -195,6 +205,8 @@ static void savePageSlice(PDFDoc *doc, bitmap->writeImgFile(splashFormatPng, stdout, x_resolution, y_resolution); } else if (jpeg) { bitmap->writeImgFile(splashFormatJpeg, stdout, x_resolution, y_resolution); + } else if (tiff) { + bitmap->writeImgFile(splashFormatTiff, stdout, x_resolution, y_resolution, TiffCompressionStr); } else { bitmap->writePNMFile(stdout); } @@ -365,7 +377,7 @@ int main(int argc, char *argv[]) { pg_h = tmp; } if (ppmRoot != NULL) { - const char *ext = png ? "png" : jpeg ? "jpg" : mono ? "pbm" : gray ? "pgm" : "ppm"; + const char *ext = png ? "png" : jpeg ? "jpg" : tiff ? "tif" : mono ? "pbm" : gray ? "pgm" : "ppm"; if (singleFile) { snprintf(ppmFile, PPM_FILE_SZ, "%.*s.%s", PPM_FILE_SZ - 32, ppmRoot, ext);
_______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
