Hi, currently, there's only SplashBitmap able to export to PBM/PGM/PPM. I just created a PNMWriter to provide generic export capabilities, even when not using Splash(Bitmap) directly. References: - PBM: http://netpbm.sourceforge.net/doc/pbm.html - PGM: http://netpbm.sourceforge.net/doc/pgm.html - PPM: http://netpbm.sourceforge.net/doc/ppm.html
Attached there's a small patch for pdftoppm to use the new export filter, instead of the own SplashBitmap PNM exporting method. -- Pino Toscano
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c61b76a..e59e34c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -228,6 +228,7 @@ set(poppler_SRCS
goo/TiffWriter.cc
goo/JpegWriter.cc
goo/ImgWriter.cc
+ goo/PNMWriter.cc
goo/gstrtod.cc
fofi/FoFiBase.cc
fofi/FoFiEncodings.cc
@@ -465,6 +466,7 @@ if(ENABLE_XPDF_HEADERS)
goo/gfile.h
goo/FixedPoint.h
goo/ImgWriter.h
+ goo/PNMWriter.h
goo/GooLikely.h
goo/gstrtod.h
DESTINATION include/poppler/goo)
diff --git a/goo/Makefile.am b/goo/Makefile.am
index be791ee..2bd348e 100644
--- a/goo/Makefile.am
+++ b/goo/Makefile.am
@@ -16,6 +16,7 @@ poppler_goo_include_HEADERS = \
PNGWriter.h \
JpegWriter.h \
TiffWriter.h \
+ PNMWriter.h \
ImgWriter.h \
GooLikely.h \
gstrtod.h
@@ -42,5 +43,6 @@ libgoo_la_SOURCES = \
PNGWriter.cc \
JpegWriter.cc \
TiffWriter.cc \
+ PNMWriter.cc \
ImgWriter.cc \
gstrtod.cc
diff --git a/goo/PNMWriter.cc b/goo/PNMWriter.cc
new file mode 100644
index 0000000..ec8609a
--- /dev/null
+++ b/goo/PNMWriter.cc
@@ -0,0 +1,117 @@
+//========================================================================
+//
+// PNMWriter.cc
+//
+// This file is licensed under the GPLv2 or later
+//
+// Copyright (C) 2010 Pino Toscano <[email protected]>
+//
+//========================================================================
+
+#include "PNMWriter.h"
+
+#include <vector>
+
+PNMWriter::PNMWriter(OutFormat formatArg)
+ : format(formatArg)
+ , file(0)
+ , imgWidth(0)
+ , rowSize(0)
+{
+}
+
+PNMWriter::~PNMWriter()
+{
+}
+
+bool PNMWriter::init(FILE *f, int width, int height, int /*hDPI*/, int /*vDPI*/)
+{
+ file = f;
+ imgWidth = width;
+
+ switch (format)
+ {
+ case PNMWriter::PBM:
+ fprintf(file, "P4\n%d %d\n", width, height);
+ rowSize = (width + 7) >> 3;
+ break;
+ case PNMWriter::PGM:
+ fprintf(file, "P5\n%d %d\n255\n", width, height);
+ rowSize = width;
+ break;
+ case PNMWriter::PPM:
+ fprintf(file, "P6\n%d %d\n255\n", width, height);
+ rowSize = width * 3;
+ break;
+ }
+
+ return true;
+}
+
+bool PNMWriter::writePointers(unsigned char **rowPointers, int rowCount)
+{
+ bool ret = true;
+ for (int i = 0; ret && (i < rowCount); ++i) {
+ ret = writeRow(&(rowPointers[i]));
+ }
+
+ return ret;
+}
+
+bool PNMWriter::writeRow(unsigned char **row)
+{
+ std::vector<unsigned char> newRow;
+ unsigned char *rowPtr = *row;
+ unsigned char *p = *row;
+
+ switch (format)
+ {
+ case PNMWriter::PBM:
+ newRow.resize(rowSize, 0);
+ rowPtr = &newRow[0];
+ for (int i = 0; i < imgWidth; ++i) {
+ unsigned char pixel = p[0];
+ if (p[0] == p[1] && p[1] == p[2]) {
+ // gray, stored already
+ } else {
+ pixel = static_cast<unsigned char>((p[0] * 11 + p[1] * 16 + p[2] * 5) / 32);
+ }
+ if (pixel < 0x7F) {
+ *(rowPtr + (i >> 3)) |= (1 << (i & 7));
+ }
+ p += 3;
+ }
+ break;
+ case PNMWriter::PGM:
+ newRow.resize(rowSize, 0);
+ rowPtr = &newRow[0];
+ for (int i = 0; i < imgWidth; ++i) {
+ if (p[0] == p[1] && p[1] == p[2]) {
+ // gray, store directly
+ newRow[i] = p[0];
+ } else {
+ // calculate the gray value
+ newRow[i] = static_cast<unsigned char>((p[0] * 11 + p[1] * 16 + p[2] * 5) / 32);
+ }
+ p += 3;
+ }
+ break;
+ case PNMWriter::PPM:
+ break;
+ }
+
+ if (int(fwrite(rowPtr, 1, rowSize, file)) < rowSize) {
+ return false;
+ }
+
+ return true;
+}
+
+bool PNMWriter::close()
+{
+ file = 0;
+ imgWidth = 0;
+ rowSize = 0;
+
+ return true;
+}
diff --git a/goo/PNMWriter.h b/goo/PNMWriter.h
new file mode 100644
index 0000000..afcc189
--- /dev/null
+++ b/goo/PNMWriter.h
@@ -0,0 +1,38 @@
+//========================================================================
+//
+// PNMWriter.h
+//
+// This file is licensed under the GPLv2 or later
+//
+// Copyright (C) 2010 Pino Toscano <[email protected]>
+//
+//========================================================================
+
+#ifndef PNMWRITER_H
+#define PNMWRITER_H
+
+#include "ImgWriter.h"
+
+class PNMWriter : public ImgWriter
+{
+ public:
+ enum OutFormat { PBM, PGM, PPM };
+
+ PNMWriter(OutFormat formatArg);
+ ~PNMWriter();
+
+ bool init(FILE *f, int width, int height, int hDPI, int vDPI);
+
+ bool writePointers(unsigned char **rowPointers, int rowCount);
+ bool writeRow(unsigned char **row);
+
+ bool close();
+
+ private:
+ const OutFormat format;
+ FILE *file;
+ int imgWidth;
+ int rowSize;
+};
+
+#endif
diff --git a/splash/SplashBitmap.cc b/splash/SplashBitmap.cc
index 7c26e54..60684d4 100644
--- a/splash/SplashBitmap.cc
+++ b/splash/SplashBitmap.cc
@@ -41,6 +41,7 @@
#include "goo/JpegWriter.h"
#include "goo/PNGWriter.h"
#include "goo/TiffWriter.h"
+#include "goo/PNMWriter.h"
#include "goo/ImgWriter.h"
//------------------------------------------------------------------------
@@ -317,6 +318,32 @@ SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, FILE *f, in
break;
#endif
+ case splashFormatPnm: {
+ PNMWriter::OutFormat fmt = PNMWriter::PPM;
+ switch (mode) {
+ case splashModeMono1:
+ fmt = PNMWriter::PBM;
+ break;
+ case splashModeMono8:
+ fmt = PNMWriter::PGM;
+ break;
+ case splashModeRGB8:
+ case splashModeBGR8:
+ case splashModeXBGR8:
+ fmt = PNMWriter::PPM;
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ // PNM doesn't support CMYK
+ error(-1, "unsupported SplashBitmap mode");
+ return splashErrGeneric;
+ break;
+#endif
+ }
+ writer = new PNMWriter(fmt);
+ break;
+ }
+
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/SplashTypes.h b/splash/SplashTypes.h
index 273c32d..fea15bf 100644
--- a/splash/SplashTypes.h
+++ b/splash/SplashTypes.h
@@ -162,7 +162,8 @@ typedef int SplashError;
enum SplashImageFileFormat {
splashFormatJpeg,
splashFormatPng,
- splashFormatTiff
+ splashFormatTiff,
+ splashFormatPnm
};
#endif
diff --git a/utils/pdftoppm.cc b/utils/pdftoppm.cc
index 8a7c702..b9ec5dc 100644
--- a/utils/pdftoppm.cc
+++ b/utils/pdftoppm.cc
@@ -194,7 +194,7 @@ static void savePageSlice(PDFDoc *doc,
} else if (tiff) {
bitmap->writeImgFile(splashFormatTiff, ppmFile, x_resolution, y_resolution, TiffCompressionStr);
} else {
- bitmap->writePNMFile(ppmFile);
+ bitmap->writeImgFile(splashFormatPnm, ppmFile, x_resolution, y_resolution);
}
} else {
#ifdef _WIN32
@@ -208,7 +208,7 @@ static void savePageSlice(PDFDoc *doc,
} else if (tiff) {
bitmap->writeImgFile(splashFormatTiff, stdout, x_resolution, y_resolution, TiffCompressionStr);
} else {
- bitmap->writePNMFile(stdout);
+ bitmap->writeImgFile(splashFormatPnm, stdout, x_resolution, y_resolution);
}
}
}
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
