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 <[email protected]> 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 <[email protected]> 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 <[email protected]> +// +//======================================================================== + +#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 <[email protected]> +// +//======================================================================== + +#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 <[email protected]> + * Copyright (C) 2010-2011, Pino Toscano <[email protected]> * * 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; } _______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
