[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