CMakeLists.txt | 5 ++ goo/Makefile.am | 9 ++- goo/PNGWriter.cc | 110 ++++++++++++++++++++++++++++++++++++++++++++++ goo/PNGWriter.h | 43 +++++++++++++++++ poppler/Makefile.am | 8 +++ splash/SplashBitmap.cc | 70 +++++++++++++++++++++++++++++ splash/SplashBitmap.h | 5 ++ splash/SplashErrorCodes.h | 4 + utils/CMakeLists.txt | 4 - utils/HtmlOutputDev.cc | 66 +++++---------------------- utils/Makefile.am | 4 - utils/pdftoppm.1 | 3 + utils/pdftoppm.cc | 21 +++++++- 13 files changed, 283 insertions(+), 69 deletions(-)
New commits: commit 92744b72df9084fd2d69ba78406898378884aed8 Author: Albert Astals Cid <[email protected]> Date: Sat Aug 8 00:20:52 2009 +0200 Add the -png flag to pdftoppm to output to PNG Based on a patch by Shen Liang <[email protected]> Also factored common PNG code from HtmlOutputDev to PNGWriter diff --git a/CMakeLists.txt b/CMakeLists.txt index d83f244..0b60c81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,6 +143,7 @@ set(poppler_SRCS goo/GooString.cc goo/gmem.cc goo/FixedPoint.cc + goo/PNGWriter.cc fofi/FoFiBase.cc fofi/FoFiEncodings.cc fofi/FoFiTrueType.cc @@ -266,7 +267,11 @@ else(MSVC) add_library(poppler SHARED ${poppler_SRCS}) endif(MSVC) set_target_properties(poppler PROPERTIES VERSION 5.0.0 SOVERSION 5) +if (ENABLE_LIBPNG) +target_link_libraries(poppler ${poppler_LIBS} ${PNG_LIBRARIES}) +else (ENABLE_LIBPNG) target_link_libraries(poppler ${poppler_LIBS}) +endif (ENABLE_LIBPNG) install(TARGETS poppler RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) if(ENABLE_XPDF_HEADERS) diff --git a/goo/Makefile.am b/goo/Makefile.am index 27aacfa..478e401 100644 --- a/goo/Makefile.am +++ b/goo/Makefile.am @@ -13,10 +13,14 @@ poppler_goo_include_HEADERS = \ gtypes.h \ gmem.h \ gfile.h \ - FixedPoint.h + FixedPoint.h \ + PNGWriter.h endif +INCLUDES = \ + -I$(top_srcdir) + libgoo_la_SOURCES = \ gfile.cc \ gmempp.cc \ @@ -25,4 +29,5 @@ libgoo_la_SOURCES = \ GooTimer.cc \ GooString.cc \ gmem.cc \ - FixedPoint.cc + FixedPoint.cc \ + PNGWriter.cc diff --git a/goo/PNGWriter.cc b/goo/PNGWriter.cc new file mode 100644 index 0000000..864c976 --- /dev/null +++ b/goo/PNGWriter.cc @@ -0,0 +1,110 @@ +//======================================================================== +// +// PNGWriter.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright (C) 2009 Warren Toomey <[email protected]> +// Copyright (C) 2009 Shen Liang <[email protected]> +// Copyright (C) 2009 Albert Astals Cid <[email protected]> +// +//======================================================================== + +#include "PNGWriter.h" + +#ifdef ENABLE_LIBPNG + +#include "poppler/Error.h" + +PNGWriter::PNGWriter() +{ +} + +PNGWriter::~PNGWriter() +{ + /* cleanup heap allocation */ + png_destroy_write_struct(&png_ptr, &info_ptr); +} + +bool PNGWriter::init(FILE *f, int width, int height) +{ + /* initialize stuff */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) { + error(-1, "png_create_write_struct failed"); + return false; + } + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + error(-1, "png_create_info_struct failed"); + return false; + } + + if (setjmp(png_jmpbuf(png_ptr))) { + error(-1, "png_jmpbuf failed"); + return false; + } + + /* write header */ + png_init_io(png_ptr, f); + if (setjmp(png_jmpbuf(png_ptr))) { + error(-1, "Error during writing header"); + return false; + } + + // Set up the type of PNG image and the compression level + png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); + + png_byte bit_depth = 8; + png_byte color_type = PNG_COLOR_TYPE_RGB; + png_byte interlace_type = PNG_INTERLACE_NONE; + + png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, interlace_type, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + png_write_info(png_ptr, info_ptr); + if (setjmp(png_jmpbuf(png_ptr))) { + error(-1, "error during writing png info bytes"); + return false; + } + + return true; +} + +bool PNGWriter::writePointers(png_bytep *rowPointers) +{ + png_write_image(png_ptr, rowPointers); + /* write bytes */ + if (setjmp(png_jmpbuf(png_ptr))) { + error(-1, "Error during writing bytes"); + return false; + } + + return true; +} + +bool PNGWriter::writeRow(png_bytep *row) +{ + // Write the row to the file + png_write_rows(png_ptr, row, 1); + if (setjmp(png_jmpbuf(png_ptr))) { + error(-1, "error during png row write"); + return false; + } + + return true; +} + +bool PNGWriter::close() +{ + /* end write */ + png_write_end(png_ptr, info_ptr); + if (setjmp(png_jmpbuf(png_ptr))) { + error(-1, "Error during end of write"); + return false; + } + + return true; +} + +#endif diff --git a/goo/PNGWriter.h b/goo/PNGWriter.h new file mode 100644 index 0000000..0540bd7 --- /dev/null +++ b/goo/PNGWriter.h @@ -0,0 +1,43 @@ +//======================================================================== +// +// PNGWriter.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright (C) 2009 Warren Toomey <[email protected]> +// Copyright (C) 2009 Shen Liang <[email protected]> +// Copyright (C) 2009 Albert Astals Cid <[email protected]> +// +//======================================================================== + +#ifndef PNGWRITER_H +#define PNGWRITER_H + +#include <config.h> + +#ifdef ENABLE_LIBPNG + +#include <cstdio> +#include <png.h> + +class PNGWriter +{ + public: + PNGWriter(); + ~PNGWriter(); + + bool init(FILE *f, int width, int height); + + bool writePointers(png_bytep *rowPointers); + bool writeRow(png_bytep *row); + + bool close(); + + private: + png_structp png_ptr; + png_infop info_ptr; +}; + +#endif + +#endif \ No newline at end of file diff --git a/poppler/Makefile.am b/poppler/Makefile.am index 35be92d..ec79e31 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -62,6 +62,13 @@ libjpeg_libs = \ endif +if BUILD_LIBPNG + +libpng_libs = \ + $(LIBPNG_LIBS) + +endif + if BUILD_LIBOPENJPEG libjpeg2000_sources = \ @@ -135,6 +142,7 @@ libpoppler_la_LIBADD = \ $(cms_libs) \ $(splash_libs) \ $(libjpeg_libs) \ + $(libpng_libs) \ $(zlib_libs) \ $(libjpeg2000_libs) \ $(abiword_libs) \ diff --git a/splash/SplashBitmap.cc b/splash/SplashBitmap.cc index 6cf2aea..84328f2 100644 --- a/splash/SplashBitmap.cc +++ b/splash/SplashBitmap.cc @@ -13,6 +13,7 @@ // // Copyright (C) 2006, 2009 Albert Astals Cid <[email protected]> // Copyright (C) 2007 Ilmari Heikkinen <[email protected]> +// Copyright (C) 2009 Shen Liang <[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 @@ -26,9 +27,12 @@ #endif #include <stdio.h> +#include <stdlib.h> #include "goo/gmem.h" #include "SplashErrorCodes.h" #include "SplashBitmap.h" +#include "poppler/Error.h" +#include "PNGWriter.h" //------------------------------------------------------------------------ // SplashBitmap @@ -181,6 +185,8 @@ SplashError SplashBitmap::writePNMFile(FILE *f) { #if SPLASH_CMYK case splashModeCMYK8: // PNM doesn't support CMYK + error(-1, "unsupported SplashBitmap mode"); + return splashErrGeneric; break; #endif } @@ -237,3 +243,67 @@ void SplashBitmap::getPixel(int x, int y, SplashColorPtr pixel) { Guchar SplashBitmap::getAlpha(int x, int y) { return alpha[y * width + x]; } + +SplashError SplashBitmap::writePNGFile(char *fileName) { + FILE *f; + SplashError e; + + if (!(f = fopen(fileName, "wb"))) { + return splashErrOpenFile; + } + + e = writePNGFile(f); + + fclose(f); + return e; +} + +SplashError SplashBitmap::writePNGFile(FILE *f) { +#ifndef ENABLE_LIBPNG + error(-1, "PNG support not compiled in"); + return splashErrGeneric; +#else + if (mode != splashModeRGB8) { + error(-1, "unsupported SplashBitmap mode"); + return splashErrGeneric; + } + + SplashColorPtr row; + + PNGWriter *writer = new PNGWriter(); + if (!writer->init(f, width, height)) { + delete writer; + return splashErrGeneric; + } + + png_bytep *row_pointers = new png_bytep[height]; + switch (mode) { + case splashModeRGB8: + row = data; + + for (int y = 0; y < height; ++y) { + row_pointers[y] = row; + row += rowSize; + } + if (!writer->writePointers(row_pointers)) { + delete[] row_pointers; + delete writer; + return splashErrGeneric; + } + break; + default: + // can't happen + break; + } + delete[] row_pointers; + + if (writer->close()) { + delete writer; + return splashErrGeneric; + } + + delete writer; + + return splashOk; +#endif +} diff --git a/splash/SplashBitmap.h b/splash/SplashBitmap.h index 8ec186a..5085763 100644 --- a/splash/SplashBitmap.h +++ b/splash/SplashBitmap.h @@ -12,6 +12,8 @@ // under GPL version 2 or later // // Copyright (C) 2007 Ilmari Heikkinen <[email protected]> +// Copyright (C) 2009 Shen Liang <[email protected]> +// Copyright (C) 2009 Albert Astals Cid <[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 @@ -55,6 +57,9 @@ public: SplashError writePNMFile(char *fileName); SplashError writePNMFile(FILE *f); + + SplashError writePNGFile(char *fileName); + SplashError writePNGFile(FILE *f); void getPixel(int x, int y, SplashColorPtr pixel); Guchar getAlpha(int x, int y); diff --git a/splash/SplashErrorCodes.h b/splash/SplashErrorCodes.h index 4224237..9c30982 100644 --- a/splash/SplashErrorCodes.h +++ b/splash/SplashErrorCodes.h @@ -11,7 +11,7 @@ // All changes made under the Poppler project to this file are licensed // under GPL version 2 or later // -// Copyright (C) 2006 Albert Astals Cid <[email protected]> +// Copyright (C) 2006, 2009 Albert Astals Cid <[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 @@ -43,4 +43,6 @@ #define splashErrZeroImage 9 // image of 0x0 +#define splashErrGeneric 255 + #endif diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index 233fdcb..f5d4911 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -69,11 +69,7 @@ set(pdftohtml_SOURCES ${common_srcs} HtmlOutputDev.cc ) add_executable(pdftohtml ${pdftohtml_SOURCES}) -if (ENABLE_LIBPNG) -target_link_libraries(pdftohtml ${common_libs} ${PNG_LIBRARIES}) -else (ENABLE_LIBPNG) target_link_libraries(pdftohtml ${common_libs}) -endif (ENABLE_LIBPNG) install(TARGETS pdftohtml DESTINATION bin) if (ENABLE_ABIWORD) diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc index 3395878..64f5098 100644 --- a/utils/HtmlOutputDev.cc +++ b/utils/HtmlOutputDev.cc @@ -51,12 +51,10 @@ #ifdef ENABLE_LIBJPEG #include "DCTStream.h" #endif -#ifdef ENABLE_LIBPNG -#include "png.h" -#endif #include "GlobalParams.h" #include "HtmlOutputDev.h" #include "HtmlFonts.h" +#include "PNGWriter.h" int HtmlPage::pgNum=0; int HtmlOutputDev::imgNum=1; @@ -1316,10 +1314,6 @@ void HtmlOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, // comes from an example by Guillaume Cottenceau. Guchar *p; GfxRGB rgb; - png_structp png_ptr; - png_infop info_ptr; - png_byte color_type= PNG_COLOR_TYPE_RGB; - png_byte bit_depth= 8; png_byte *row = (png_byte *) malloc(3 * width); // 3 bytes/pixel: RGB png_bytep *row_pointer= &row; @@ -1339,42 +1333,11 @@ void HtmlOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, return; } - // Initialize the PNG stuff - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png_ptr) { - error(-1, "png_create_write_struct failed"); - return; - } - - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - error(-1, "png_create_info_struct failed"); - return; - } - if (setjmp(png_jmpbuf(png_ptr))) { - error(-1, "error during init_io"); - return; - } - - // Write the PNG header - png_init_io(png_ptr, f1); - if (setjmp(png_jmpbuf(png_ptr))) { - error(-1, "error during writing png header"); - return; - } - - // Set up the type of PNG image and the compression level - png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); - - png_set_IHDR(png_ptr, info_ptr, width, height, - bit_depth, color_type, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - // Write the image info bytes - png_write_info(png_ptr, info_ptr); - if (setjmp(png_jmpbuf(png_ptr))) { - error(-1, "error during writing png info bytes"); - return; + PNGWriter *writer = new PNGWriter(); + if (!writer->init(f1, width, height)) { + delete writer; + fclose(f1); + return; } // Initialize the image stream @@ -1396,22 +1359,17 @@ void HtmlOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, p += colorMap->getNumPixelComps(); } - // Write the row to the file - png_write_rows(png_ptr, row_pointer, 1); - if (setjmp(png_jmpbuf(png_ptr))) { - error(-1, "error during png row write"); + if (!writer->writeRow(row_pointer)) { + delete writer; + fclose(f1); return; } } - // Finish off the PNG file - png_write_end(png_ptr, info_ptr); - if (setjmp(png_jmpbuf(png_ptr))) { - error(-1, "error during png end of write"); - return; - } - + writer->close(); + delete writer; fclose(f1); + free(row); imgList->append(fName); ++imgNum; diff --git a/utils/Makefile.am b/utils/Makefile.am index ed7e7c1..f44687f 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -35,10 +35,6 @@ pdftoabw_binary = pdftoabw endif -if BUILD_LIBPNG -pdftohtml_LDADD = $(LDADD) $(LIBPNG_LIBS) -endif - AM_LDFLAGS = @auto_import_flags@ bin_PROGRAMS = \ diff --git a/utils/pdftoppm.1 b/utils/pdftoppm.1 index 5ad95ed..ecadf22 100644 --- a/utils/pdftoppm.1 +++ b/utils/pdftoppm.1 @@ -68,6 +68,9 @@ Generate a monochrome PBM file (instead of a color PPM file). .B \-gray Generate a grayscale PGM file (instead of a color PPM file). .TP +.B \-png +Generates a PNG file instead a PPM file. +.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 17e37d8..38c26fd 100644 --- a/utils/pdftoppm.cc +++ b/utils/pdftoppm.cc @@ -16,6 +16,7 @@ // Copyright (C) 2007 Ilmari Heikkinen <[email protected]> // Copyright (C) 2008 Richard Airlie <[email protected]> // Copyright (C) 2009 Michael K. Johnson <[email protected]> +// Copyright (C) 2009 Shen Liang <[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 @@ -54,6 +55,7 @@ static int sz = 0; static GBool useCropBox = gFalse; static GBool mono = gFalse; static GBool gray = gFalse; +static GBool png = gFalse; static char enableFreeTypeStr[16] = ""; static char antialiasStr[16] = ""; static char vectorAntialiasStr[16] = ""; @@ -99,7 +101,10 @@ static const ArgDesc argDesc[] = { "generate a monochrome PBM file"}, {"-gray", argFlag, &gray, 0, "generate a grayscale PGM file"}, - +#if ENABLE_LIBPNG + {"-png", argFlag, &png, 0, + "generate a PNG file"}, +#endif #if HAVE_FREETYPE_FREETYPE_H | HAVE_FREETYPE_H {"-freetype", argString, enableFreeTypeStr, sizeof(enableFreeTypeStr), "enable FreeType font rasterizer: yes, no"}, @@ -146,9 +151,17 @@ static void savePageSlice(PDFDoc *doc, x, y, w, h ); if (ppmFile != NULL) { - splashOut->getBitmap()->writePNMFile(ppmFile); + if (png) { + splashOut->getBitmap()->writePNGFile(ppmFile); + } else { + splashOut->getBitmap()->writePNMFile(ppmFile); + } } else { - splashOut->getBitmap()->writePNMFile(stdout); + if (png) { + splashOut->getBitmap()->writePNGFile(stdout); + } else { + splashOut->getBitmap()->writePNMFile(stdout); + } } } @@ -288,7 +301,7 @@ int main(int argc, char *argv[]) { if (ppmRoot != NULL) { snprintf(ppmFile, PPM_FILE_SZ, "%.*s-%0*d.%s", PPM_FILE_SZ - 32, ppmRoot, pg_num_len, pg, - mono ? "pbm" : gray ? "pgm" : "ppm"); + png ? "png" : mono ? "pbm" : gray ? "pgm" : "ppm"); savePageSlice(doc, splashOut, pg, x, y, w, h, pg_w, pg_h, ppmFile); } else { savePageSlice(doc, splashOut, pg, x, y, w, h, pg_w, pg_h, NULL); _______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
