[PATCH] Add the -jpeg flag to pdftoppm to output to JPEG

Stefan Thomas thomas at eload24.com
Mon Sep 7 01:55:40 PDT 2009


---
 goo/JpegWriter.cc      |   75 +++++++++++++++++++++++++++++++++
 goo/JpegWriter.h       |   44 +++++++++++++++++++
 goo/Makefile.am        |    2 +
 splash/SplashBitmap.cc |  109 ++++++++++++++++++++++++++++++++++++++++++++++++
 splash/SplashBitmap.h  |    3 +
 utils/pdftoppm.cc      |   11 ++++-
 6 files changed, 243 insertions(+), 1 deletions(-)
 create mode 100644 goo/JpegWriter.cc
 create mode 100644 goo/JpegWriter.h

diff --git a/goo/JpegWriter.cc b/goo/JpegWriter.cc
new file mode 100644
index 0000000..abc1fba
--- /dev/null
+++ b/goo/JpegWriter.cc
@@ -0,0 +1,75 @@
+//========================================================================
+//
+// JpegWriter.cc
+//
+// This file is licensed under the GPLv2 or later
+//
+// Copyright (C) 2009 Stefan Thomas <thomas at eload24.com>
+// 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 "JpegWriter.h"
+
+#ifdef ENABLE_LIBJPEG
+
+#include "poppler/Error.h"
+
+JpegWriter::JpegWriter()
+{
+}
+
+JpegWriter::~JpegWriter()
+{
+	// cleanup
+	jpeg_destroy_compress(&cinfo);
+}
+
+bool JpegWriter::init(FILE *f, int width, int height)
+{
+	// Initialize libjpeg
+	cinfo.err = jpeg_std_error(&jerr);
+	jpeg_create_compress(&cinfo);
+	
+	// Set destination file
+	jpeg_stdio_dest(&cinfo, f);
+	
+	// Set libjpeg configuration
+	cinfo.image_width = width;
+	cinfo.image_height = height;
+	cinfo.input_components = 3;     /* # of color components per pixel */
+	cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
+	jpeg_set_defaults(&cinfo);
+	
+	// Get ready for data
+	jpeg_start_compress(&cinfo, TRUE);
+	
+	return true;
+}
+
+bool JpegWriter::writePointers(JSAMPARRAY rowPointers, int rowCount)
+{
+	// Write all rows to the file
+	jpeg_write_scanlines(&cinfo, rowPointers, rowCount);
+	
+	return true;
+}
+
+bool JpegWriter::writeRow(JSAMPROW *row)
+{
+	// Write the row to the file
+	jpeg_write_scanlines(&cinfo, row, 1);
+	
+	return true;
+}
+
+bool JpegWriter::close()
+{
+	jpeg_finish_compress(&cinfo);
+	
+	return true;
+}
+
+#endif
diff --git a/goo/JpegWriter.h b/goo/JpegWriter.h
new file mode 100644
index 0000000..6773f7b
--- /dev/null
+++ b/goo/JpegWriter.h
@@ -0,0 +1,44 @@
+//========================================================================
+//
+// JpegWriter.h
+//
+// This file is licensed under the GPLv2 or later
+//
+// Copyright (C) 2009 Stefan Thomas <thomas at eload24.com>
+// 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 JPEGWRITER_H
+#define JPEGWRITER_H
+
+#include <config.h>
+
+#ifdef ENABLE_LIBJPEG
+
+#include <cstdio>
+#include <jpeglib.h>
+
+class JpegWriter
+{
+	public:
+		JpegWriter();
+		~JpegWriter();
+		
+		bool init(FILE *f, int width, int height);
+		
+		bool writePointers(JSAMPARRAY rowPointers, int rowCount);
+		bool writeRow(JSAMPROW *row);
+		
+		bool close();
+	
+	private:
+		struct jpeg_compress_struct cinfo;
+		struct jpeg_error_mgr jerr;
+};
+
+#endif
+
+#endif
diff --git a/goo/Makefile.am b/goo/Makefile.am
index f10fd15..ad11af5 100644
--- a/goo/Makefile.am
+++ b/goo/Makefile.am
@@ -15,6 +15,7 @@ poppler_goo_include_HEADERS =			\
 	gfile.h					\
 	FixedPoint.h				\
 	PNGWriter.h				\
+	JpegWriter.h				\
 	gstrtod.h
 
 endif
@@ -32,4 +33,5 @@ libgoo_la_SOURCES =				\
 	gmem.cc					\
 	FixedPoint.cc				\
 	PNGWriter.cc				\
+	JpegWriter.cc				\
 	gstrtod.cc
diff --git a/splash/SplashBitmap.cc b/splash/SplashBitmap.cc
index 25a71a0..d2eca16 100644
--- a/splash/SplashBitmap.cc
+++ b/splash/SplashBitmap.cc
@@ -33,6 +33,7 @@
 #include "SplashBitmap.h"
 #include "poppler/Error.h"
 #include "PNGWriter.h"
+#include "JpegWriter.h"
 
 //------------------------------------------------------------------------
 // SplashBitmap
@@ -351,3 +352,111 @@ SplashError SplashBitmap::writePNGFile(FILE *f) {
   return splashOk;
 #endif
 }
+
+SplashError SplashBitmap::writeJpegFile(char *fileName) {
+  FILE *f;
+  SplashError e;
+
+  if (!(f = fopen(fileName, "wb"))) {
+    return splashErrOpenFile;
+  }
+
+  e = writeJpegFile(f);
+  
+  fclose(f);
+  return e;
+}
+
+SplashError SplashBitmap::writeJpegFile(FILE *f) {
+#ifndef ENABLE_LIBJPEG
+  error(-1, "JPEG support not compiled in");
+  return splashErrGeneric;
+#else
+  if (mode != splashModeRGB8 && mode != splashModeMono8 && mode != splashModeMono1) {
+    error(-1, "unsupported SplashBitmap mode");
+    return splashErrGeneric;
+  }
+
+  JpegWriter *writer = new JpegWriter();
+  if (!writer->init(f, width, height)) {
+    delete writer;
+    return splashErrGeneric;
+  }
+
+  switch (mode) {
+    case splashModeRGB8:
+    {
+      SplashColorPtr row;
+      png_bytep *row_pointers = new png_bytep[height];
+      row = data;
+
+      for (int y = 0; y < height; ++y) {
+        row_pointers[y] = row;
+        row += rowSize;
+      }
+      if (!writer->writePointers(row_pointers, height)) {
+        delete[] row_pointers;
+        delete writer;
+        return splashErrGeneric;
+      }
+      delete[] row_pointers;
+    }
+    break;
+    
+    case splashModeMono8:
+    {
+      png_byte *row = new png_byte[3 * width];
+      for (int y = 0; y < height; y++) {
+        // Convert into a PNG row
+        for (int x = 0; x < width; x++) {
+          row[3*x] = data[y * rowSize + x];
+          row[3*x+1] = data[y * rowSize + x];
+          row[3*x+2] = data[y * rowSize + x];
+        }
+
+        if (!writer->writeRow(&row)) {
+          delete[] row;
+          delete writer;
+          return splashErrGeneric;
+        }
+      }
+      delete[] row;
+    }
+    break;
+    
+    case splashModeMono1:
+    {
+      png_byte *row = new png_byte[3 * width];
+      for (int y = 0; y < height; y++) {
+        // Convert into a PNG row
+        for (int x = 0; x < width; x++) {
+          getPixel(x, y, &row[3*x]);
+          row[3*x+1] = row[3*x];
+          row[3*x+2] = row[3*x];
+        }
+
+        if (!writer->writeRow(&row)) {
+          delete[] row;
+          delete writer;
+          return splashErrGeneric;
+        }
+      }
+      delete[] row;
+    }
+    break;
+    
+    default:
+    // can't happen
+    break;
+  }
+  
+  if (writer->close()) {
+    delete writer;
+    return splashErrGeneric;
+  }
+
+  delete writer;
+
+  return splashOk;
+#endif
+}
diff --git a/splash/SplashBitmap.h b/splash/SplashBitmap.h
index 5085763..9de0226 100644
--- a/splash/SplashBitmap.h
+++ b/splash/SplashBitmap.h
@@ -60,6 +60,9 @@ public:
   
   SplashError writePNGFile(char *fileName);
   SplashError writePNGFile(FILE *f);
+  
+  SplashError writeJpegFile(char *fileName);
+  SplashError writeJpegFile(FILE *f);
 
   void getPixel(int x, int y, SplashColorPtr pixel);
   Guchar getAlpha(int x, int y);
diff --git a/utils/pdftoppm.cc b/utils/pdftoppm.cc
index 38c26fd..f3c2a49 100644
--- a/utils/pdftoppm.cc
+++ b/utils/pdftoppm.cc
@@ -56,6 +56,7 @@ static GBool useCropBox = gFalse;
 static GBool mono = gFalse;
 static GBool gray = gFalse;
 static GBool png = gFalse;
+static GBool jpeg = gFalse;
 static char enableFreeTypeStr[16] = "";
 static char antialiasStr[16] = "";
 static char vectorAntialiasStr[16] = "";
@@ -105,6 +106,10 @@ static const ArgDesc argDesc[] = {
   {"-png",    argFlag,     &png,           0,
    "generate a PNG file"},
 #endif
+#if ENABLE_LIBJPEG
+  {"-jpeg",    argFlag,     &jpeg,           0,
+   "generate a JPEG file"},
+#endif
 #if HAVE_FREETYPE_FREETYPE_H | HAVE_FREETYPE_H
   {"-freetype",   argString,      enableFreeTypeStr, sizeof(enableFreeTypeStr),
    "enable FreeType font rasterizer: yes, no"},
@@ -153,12 +158,16 @@ static void savePageSlice(PDFDoc *doc,
   if (ppmFile != NULL) {
     if (png) {
       splashOut->getBitmap()->writePNGFile(ppmFile);
+    } else if (jpeg) {
+      splashOut->getBitmap()->writeJpegFile(ppmFile);
     } else {
       splashOut->getBitmap()->writePNMFile(ppmFile);
     }
   } else {
     if (png) {
       splashOut->getBitmap()->writePNGFile(stdout);
+    } else if (jpeg) {
+      splashOut->getBitmap()->writeJpegFile(stdout);
     } else {
       splashOut->getBitmap()->writePNMFile(stdout);
     }
@@ -301,7 +310,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,
-              png ? "png" : mono ? "pbm" : gray ? "pgm" : "ppm");
+              png ? "png" : jpeg ? "jpg" : 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);
-- 
1.6.0.4


--------------010409070708070506000101--


More information about the poppler mailing list