[poppler] 2 commits - cpp/CMakeLists.txt cpp/Makefile.am cpp/PNMWriter.cc cpp/PNMWriter.h cpp/poppler-image.cpp
Pino Toscano
pino at kemper.freedesktop.org
Wed Jan 5 16:16:02 PST 2011
cpp/CMakeLists.txt | 1
cpp/Makefile.am | 2
cpp/PNMWriter.cc | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++
cpp/PNMWriter.h | 43 ++++++++++++++++++
cpp/poppler-image.cpp | 23 +++++++++
5 files changed, 187 insertions(+), 1 deletion(-)
New commits:
commit 1324ae13f1fc2fa28951c2c7f7d63d4756537229
Author: Pino Toscano <pino at kde.org>
Date: Thu Jan 6 01:15:30 2011 +0100
[cpp/apidox] advertize the 'pnm' image format
diff --git a/cpp/poppler-image.cpp b/cpp/poppler-image.cpp
index 61f4c1e..8e9ac63 100644
--- a/cpp/poppler-image.cpp
+++ b/cpp/poppler-image.cpp
@@ -330,6 +330,7 @@ image image::copy(const rect &r) const
\li PNG: \c png
\li JPEG: \c jpeg, \c jpg
\li TIFF: \c tiff
+ \li PNM: \c pnm (with Poppler >= 0.18)
If an image format is not supported (check the result of
supported_image_formats()), the saving fails.
commit b192363960c26111167b1b08db9910e5f39dcf8b
Author: Pino Toscano <pino at kde.org>
Date: Thu Jan 6 01:09:09 2011 +0100
[cpp] Add PNM (PBM/PGM/PPM) exporting to 'image'.
Introduce a custom ImgWriter (PNMWriter) for exporting in the PNM variants,
and use it choosing the output format matching as close as possible the format of the image.
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index e606988..af61606 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -8,6 +8,7 @@ configure_file(poppler-version.h.in ${CMAKE_CURRENT_BINARY_DIR}/poppler-version.
add_subdirectory(tests)
set(poppler_cpp_SRCS
+ PNMWriter.cc
poppler-document.cpp
poppler-embedded-file.cpp
poppler-font.cpp
diff --git a/cpp/Makefile.am b/cpp/Makefile.am
index eddbde3..6d4954b 100644
--- a/cpp/Makefile.am
+++ b/cpp/Makefile.am
@@ -21,6 +21,8 @@ poppler_include_HEADERS = \
lib_LTLIBRARIES = libpoppler-cpp.la
libpoppler_cpp_la_SOURCES = \
+ PNMWriter.cc \
+ PNMWriter.h \
poppler-document.cpp \
poppler-document-private.h \
poppler-embedded-file.cpp \
diff --git a/cpp/PNMWriter.cc b/cpp/PNMWriter.cc
new file mode 100644
index 0000000..a2b9a77
--- /dev/null
+++ b/cpp/PNMWriter.cc
@@ -0,0 +1,119 @@
+//========================================================================
+//
+// PNMWriter.cc
+//
+// This file is licensed under the GPLv2 or later
+//
+// Copyright (C) 2011 Pino Toscano <pino at kde.org>
+//
+//========================================================================
+
+#include "PNMWriter.h"
+
+#include <vector>
+
+using namespace poppler;
+
+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/cpp/PNMWriter.h b/cpp/PNMWriter.h
new file mode 100644
index 0000000..8d8da2d
--- /dev/null
+++ b/cpp/PNMWriter.h
@@ -0,0 +1,43 @@
+//========================================================================
+//
+// PNMWriter.h
+//
+// This file is licensed under the GPLv2 or later
+//
+// Copyright (C) 2011 Pino Toscano <pino at kde.org>
+//
+//========================================================================
+
+#ifndef PNMWRITER_H
+#define PNMWRITER_H
+
+#include "ImgWriter.h"
+
+namespace poppler
+{
+
+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/cpp/poppler-image.cpp b/cpp/poppler-image.cpp
index ef213a5..61f4c1e 100644
--- a/cpp/poppler-image.cpp
+++ b/cpp/poppler-image.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, Pino Toscano <pino at kde.org>
+ * Copyright (C) 2010-2011, Pino Toscano <pino at kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,6 +31,7 @@
#if defined(ENABLE_LIBTIFF)
#include "TiffWriter.h"
#endif
+#include "PNMWriter.h"
#include <cstdlib>
#include <cstring>
@@ -38,6 +39,8 @@
#include <memory>
#include <vector>
+using poppler::PNMWriter;
+
namespace {
struct FileCloser {
@@ -66,6 +69,19 @@ int calc_bytes_per_row(int width, poppler::image::format_enum format)
return 0;
}
+PNMWriter::OutFormat pnm_format(poppler::image::format_enum format)
+{
+ switch (format) {
+ case poppler::image::format_invalid: // unused, anyway
+ case poppler::image::format_mono:
+ return PNMWriter::PBM;
+ case poppler::image::format_rgb24:
+ case poppler::image::format_argb32:
+ return PNMWriter::PPM;
+ }
+ return PNMWriter::PPM;
+}
+
}
using namespace poppler;
@@ -348,6 +364,9 @@ bool image::save(const std::string &file_name, const std::string &out_format, in
w.reset(new TiffWriter());
}
#endif
+ else if (fmt == "pnm") {
+ w.reset(new PNMWriter(pnm_format(d->format)));
+ }
if (!w.get()) {
return false;
}
@@ -418,6 +437,7 @@ std::vector<std::string> image::supported_image_formats()
#if defined(ENABLE_LIBTIFF)
formats.push_back("tiff");
#endif
+ formats.push_back("pnm");
return formats;
}
More information about the poppler
mailing list