[poppler] CMakeLists.txt goo/Makefile.am goo/PNGWriter.cc goo/PNGWriter.h poppler/Makefile.am splash/SplashBitmap.cc splash/SplashBitmap.h splash/SplashErrorCodes.h utils/CMakeLists.txt utils/HtmlOutputDev.cc utils/Makefile.am utils/pdftoppm.1 utils/pdftoppm.cc

Albert Astals Cid aacid at kemper.freedesktop.org
Fri Aug 7 15:23:00 PDT 2009


 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 <aacid at kde.org>
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 <shenzhuxi at gmail.com>
    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 <wkt at tuhs.org>
+// Copyright (C) 2009 Shen Liang <shenzhuxi at gmail.com>
+// Copyright (C) 2009 Albert Astals Cid <aacid at kde.org>
+//
+//========================================================================
+
+#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 <wkt at tuhs.org>
+// Copyright (C) 2009 Shen Liang <shenzhuxi at gmail.com>
+// Copyright (C) 2009 Albert Astals Cid <aacid at kde.org>
+//
+//========================================================================
+
+#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 <aacid at kde.org>
 // Copyright (C) 2007 Ilmari Heikkinen <ilmari.heikkinen at gmail.com>
+// Copyright (C) 2009 Shen Liang <shenzhuxi at gmail.com>
 //
 // 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 <ilmari.heikkinen at gmail.com>
+// Copyright (C) 2009 Shen Liang <shenzhuxi at gmail.com>
+// Copyright (C) 2009 Albert Astals Cid <aacid at kde.org>
 //
 // 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 <aacid at kde.org>
+// Copyright (C) 2006, 2009 Albert Astals Cid <aacid at kde.org>
 //
 // 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 <ilmari.heikkinen at gmail.com>
 // Copyright (C) 2008 Richard Airlie <richard.airlie at maglabs.net>
 // Copyright (C) 2009 Michael K. Johnson <a1237 at danlj.org>
+// Copyright (C) 2009 Shen Liang <shenzhuxi at gmail.com>
 //
 // 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);


More information about the poppler mailing list