[poppler] cpp/poppler-image.cpp cpp/poppler-image.h cpp/poppler-page-renderer.cpp cpp/poppler-page-renderer.h

Albert Astals Cid aacid at kemper.freedesktop.org
Fri May 4 13:25:54 UTC 2018


 cpp/poppler-image.cpp         |   46 +++++++++++++++
 cpp/poppler-image.h           |    5 +
 cpp/poppler-page-renderer.cpp |  124 +++++++++++++++++++++++++++++++++++++++++-
 cpp/poppler-page-renderer.h   |   13 ++++
 4 files changed, 184 insertions(+), 4 deletions(-)

New commits:
commit 7bd0f774508f543616ebb2ad1f4558fdacfca5b7
Author: Zsombor Hollay-Horvath <hollay.horvath at gmail.com>
Date:   Fri May 4 15:23:21 2018 +0200

    cpp: Expose more image modes, add option to select mode in renderer
    
    Bug #105558

diff --git a/cpp/poppler-image.cpp b/cpp/poppler-image.cpp
index 9f7d8611..6bd43f7d 100644
--- a/cpp/poppler-image.cpp
+++ b/cpp/poppler-image.cpp
@@ -3,6 +3,7 @@
  * Copyright (C) 2013 Adrian Johnson <ajohnson at redneon.com>
  * Copyright (C) 2017, 2018, Albert Astals Cid <aacid at kde.org>
  * Copyright (C) 2017, Jeroen Ooms <jeroenooms at gmail.com>
+ * Copyright (C) 2018, Zsombor Hollay-Horvath <hollay.horvath at gmail.com>
  *
  * 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
@@ -64,8 +65,11 @@ int calc_bytes_per_row(int width, poppler::image::format_enum format)
         return 0;
     case poppler::image::format_mono:
         return (width + 7) >> 3;
+    case poppler::image::format_gray8:
+        return (width + 3) >> 2 << 2;
     case poppler::image::format_rgb24:
-        return width * 3;
+    case poppler::image::format_bgr24:
+        return (width * 3 + 3) >> 2 << 2;
     case poppler::image::format_argb32:
         return width * 4;
     }
@@ -78,7 +82,9 @@ NetPBMWriter::Format pnm_format(poppler::image::format_enum format)
     case poppler::image::format_invalid: // unused, anyway
     case poppler::image::format_mono:
         return NetPBMWriter::MONOCHROME;
+    case poppler::image::format_gray8:
     case poppler::image::format_rgb24:
+    case poppler::image::format_bgr24:
     case poppler::image::format_argb32:
         return NetPBMWriter::RGB;
     }
@@ -168,6 +174,8 @@ image_private *image_private::create_data(char *data, int width, int height, ima
  \enum poppler::image::format_enum
 
  The possible formats for an image.
+
+ format_gray8 and format_bgr24 were introduced in poppler 0.65.
 */
 
 
@@ -387,6 +395,42 @@ bool image::save(const std::string &file_name, const std::string &out_format, in
         return false;
     case format_mono:
         return false;
+    case format_gray8: {
+        std::vector<unsigned char> row(3 * d->width);
+        char *hptr = d->data;
+        for (int y = 0; y < d->height; ++y) {
+            unsigned char *rowptr = &row[0];
+            for (int x = 0; x < d->width; ++x, rowptr += 3) {
+                rowptr[0] = *reinterpret_cast<unsigned char *>(hptr + x);
+                rowptr[1] = *reinterpret_cast<unsigned char *>(hptr + x);
+                rowptr[2] = *reinterpret_cast<unsigned char *>(hptr + x);
+            }
+            rowptr = &row[0];
+            if (!w->writeRow(&rowptr)) {
+                return false;
+            }
+            hptr += d->bytes_per_row;
+        }
+        break;
+    }
+    case format_bgr24: {
+        std::vector<unsigned char> row(3 * d->width);
+        char *hptr = d->data;
+        for (int y = 0; y < d->height; ++y) {
+            unsigned char *rowptr = &row[0];
+            for (int x = 0; x < d->width; ++x, rowptr += 3) {
+                rowptr[0] = *reinterpret_cast<unsigned char *>(hptr + x * 3 + 2);
+                rowptr[1] = *reinterpret_cast<unsigned char *>(hptr + x * 3 + 1);
+                rowptr[2] = *reinterpret_cast<unsigned char *>(hptr + x * 3);
+            }
+            rowptr = &row[0];
+            if (!w->writeRow(&rowptr)) {
+                return false;
+            }
+            hptr += d->bytes_per_row;
+        }
+        break;
+    }
     case format_rgb24: {
         char *hptr = d->data;
         for (int y = 0; y < d->height; ++y) {
diff --git a/cpp/poppler-image.h b/cpp/poppler-image.h
index 4f2e3017..030ed1d1 100644
--- a/cpp/poppler-image.h
+++ b/cpp/poppler-image.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010, Pino Toscano <pino at kde.org>
+ * Copyright (C) 2018, Zsombor Hollay-Horvath <hollay.horvath at gmail.com>
  *
  * 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
@@ -34,7 +35,9 @@ public:
         format_invalid,
         format_mono,
         format_rgb24,
-        format_argb32
+        format_argb32,
+        format_gray8,
+        format_bgr24
     };
 
     image();
diff --git a/cpp/poppler-page-renderer.cpp b/cpp/poppler-page-renderer.cpp
index 4c646846..fd28d9b1 100644
--- a/cpp/poppler-page-renderer.cpp
+++ b/cpp/poppler-page-renderer.cpp
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2010, Pino Toscano <pino at kde.org>
  * Copyright (C) 2015 William Bader <williambader at hotmail.com>
+ * Copyright (C) 2018, Zsombor Hollay-Horvath <hollay.horvath at gmail.com>
  *
  * 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
@@ -21,6 +22,7 @@
 
 #include "poppler-document-private.h"
 #include "poppler-page-private.h"
+#include "poppler-image.h"
 
 #include <config.h>
 
@@ -38,14 +40,72 @@ public:
     page_renderer_private()
         : paper_color(0xffffffff)
         , hints(0)
+        , image_format(image::format_enum::format_argb32)
+        , line_mode(page_renderer::line_mode_enum::line_default)
     {
     }
 
+#if defined(HAVE_SPLASH)
+    static bool conv_color_mode(image::format_enum mode,
+                                SplashColorMode &splash_mode);
+    static bool conv_line_mode(page_renderer::line_mode_enum mode,
+                               SplashThinLineMode &splash_mode);
+#endif
+
     argb paper_color;
     unsigned int hints;
+    image::format_enum image_format;
+    page_renderer::line_mode_enum line_mode;
+
 };
 
 
+#if defined(HAVE_SPLASH)
+bool page_renderer_private::conv_color_mode(image::format_enum mode,
+                                            SplashColorMode &splash_mode)
+{
+    switch (mode) {
+        case image::format_enum::format_mono:
+            splash_mode = splashModeMono1;
+            break;
+        case image::format_enum::format_gray8:
+            splash_mode = splashModeMono8;
+            break;
+        case image::format_enum::format_rgb24:
+            splash_mode = splashModeRGB8;
+            break;
+        case image::format_enum::format_bgr24:
+            splash_mode = splashModeBGR8;
+            break;
+        case image::format_enum::format_argb32:
+            splash_mode = splashModeXBGR8;
+            break;
+        default:
+            return false;
+    }
+    return true;
+}
+
+bool page_renderer_private::conv_line_mode(page_renderer::line_mode_enum mode,
+                                           SplashThinLineMode &splash_mode)
+{
+    switch (mode) {
+        case page_renderer::line_mode_enum::line_default:
+            splash_mode = splashThinLineDefault;
+            break;
+        case page_renderer::line_mode_enum::line_solid:
+            splash_mode = splashThinLineSolid;
+            break;
+        case page_renderer::line_mode_enum::line_shape:
+            splash_mode = splashThinLineShape;
+            break;
+        default:
+            return false;
+    }
+    return true;
+}
+#endif
+
 /**
  \class poppler::page_renderer poppler-page-renderer.h "poppler/cpp/poppler-renderer.h"
 
@@ -137,6 +197,58 @@ void page_renderer::set_render_hints(unsigned int hints)
 }
 
 /**
+ The image format used when rendering.
+
+ By default ARGB32 is set.
+
+ \returns the image format
+
+ \since 0.65
+ */
+image::format_enum page_renderer::image_format() const
+{
+    return d->image_format;
+}
+
+/**
+ Set new image format used when rendering.
+
+ \param format the new image format
+
+ \since 0.65
+ */
+void page_renderer::set_image_format(image::format_enum format)
+{
+    d->image_format = format;
+}
+
+/**
+ The line mode used when rendering.
+
+ By default default mode is set.
+
+ \returns the line mode
+
+ \since 0.65
+ */
+page_renderer::line_mode_enum page_renderer::line_mode() const
+{
+    return d->line_mode;
+}
+
+/**
+ Set new line mode used when rendering.
+
+ \param mode the new line mode
+
+ \since 0.65
+ */
+void page_renderer::set_line_mode(page_renderer::line_mode_enum mode)
+{
+    d->line_mode = mode;
+}
+
+/**
  Render the specified page.
 
  This functions renders the specified page on an image following the specified
@@ -168,11 +280,19 @@ image page_renderer::render_page(const page *p,
     page_private *pp = page_private::get(p);
     PDFDoc *pdfdoc = pp->doc->doc;
 
+    SplashColorMode colorMode;
+    SplashThinLineMode lineMode;
+
+    if (!d->conv_color_mode(d->image_format, colorMode) ||
+        !d->conv_line_mode(d->line_mode, lineMode)) {
+        return image();
+    }
+
     SplashColor bgColor;
     bgColor[0] = d->paper_color & 0xff;
     bgColor[1] = (d->paper_color >> 8) & 0xff;
     bgColor[2] = (d->paper_color >> 16) & 0xff;
-    SplashOutputDev splashOutputDev(splashModeXBGR8, 4, gFalse, bgColor, gTrue);
+    SplashOutputDev splashOutputDev(colorMode, 4, gFalse, bgColor, gTrue, lineMode);
     splashOutputDev.setFontAntialias(d->hints & text_antialiasing ? gTrue : gFalse);
     splashOutputDev.setVectorAntialias(d->hints & antialiasing ? gTrue : gFalse);
     splashOutputDev.setFreeTypeHinting(d->hints & text_hinting ? gTrue : gFalse, gFalse);
@@ -188,7 +308,7 @@ image page_renderer::render_page(const page *p,
 
     SplashColorPtr data_ptr = bitmap->getDataPtr();
 
-    const image img(reinterpret_cast<char *>(data_ptr), bw, bh, image::format_argb32);
+    const image img(reinterpret_cast<char *>(data_ptr), bw, bh, d->image_format);
     return img.copy();
 #else
     return image();
diff --git a/cpp/poppler-page-renderer.h b/cpp/poppler-page-renderer.h
index 13838658..368281a8 100644
--- a/cpp/poppler-page-renderer.h
+++ b/cpp/poppler-page-renderer.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010, Pino Toscano <pino at kde.org>
+ * Copyright (C) 2018, Zsombor Hollay-Horvath <hollay.horvath at gmail.com>
  *
  * 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
@@ -39,6 +40,12 @@ public:
         text_hinting = 0x00000004
     };
 
+    enum line_mode_enum {
+        line_default,
+        line_solid,
+        line_shape
+    };
+
     page_renderer();
     ~page_renderer();
 
@@ -49,6 +56,12 @@ public:
     void set_render_hint(render_hint hint, bool on = true);
     void set_render_hints(unsigned int hints);
 
+    image::format_enum image_format() const;
+    void set_image_format(image::format_enum format);
+
+    line_mode_enum line_mode() const;
+    void set_line_mode(line_mode_enum mode);
+
     image render_page(const page *p,
                       double xres = 72.0, double yres = 72.0,
                       int x = -1, int y = -1, int w = -1, int h = -1,


More information about the poppler mailing list