[libgxps] tools: Add generic converter to image formats



commit 9a1bc870fc39cc54a6b500b3a63fc375d887d385
Author: Carlos Garcia Campos <carlosgc gnome org>
Date:   Sat Oct 29 11:53:33 2011 +0200

    tools: Add generic converter to image formats
    
    It implements some of the GXPSConverter methods but it's also an
    bastract class that needs concrete implementation for every image output
    format.

 tools/Makefile.am            |    6 +-
 tools/gxps-image-converter.c |  195 ++++++++++++++++++++++++++++++++++++++++++
 tools/gxps-image-converter.h |   56 ++++++++++++
 tools/gxps-image-writer.c    |   61 +++++++++++++
 tools/gxps-image-writer.h    |   64 ++++++++++++++
 5 files changed, 381 insertions(+), 1 deletions(-)
---
diff --git a/tools/Makefile.am b/tools/Makefile.am
index cf7582a..9656fab 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -2,7 +2,11 @@ noinst_LTLIBRARIES = libgxpstools.la
 
 libgxpstools_la_SOURCES = \
 	gxps-converter.c	\
-	gxps-converter.h
+	gxps-converter.h	\
+	gxps-image-converter.c	\
+	gxps-image-converter.h	\
+	gxps-image-writer.c	\
+	gxps-image-writer.h
 
 libgxpstools_la_CPPFLAGS = \
 	-I$(top_srcdir)		\
diff --git a/tools/gxps-image-converter.c b/tools/gxps-image-converter.c
new file mode 100644
index 0000000..b7ae18f
--- /dev/null
+++ b/tools/gxps-image-converter.c
@@ -0,0 +1,195 @@
+/* GXPSImageConverter
+ *
+ * Copyright (C) 2011  Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <config.h>
+
+#include "gxps-image-converter.h"
+#include <stdint.h>
+#include <math.h>
+#include <string.h>
+#include <libgxps/gxps.h>
+
+G_DEFINE_ABSTRACT_TYPE (GXPSImageConverter, gxps_image_converter, GXPS_TYPE_CONVERTER)
+
+static guint
+get_n_digits (GXPSDocument *document)
+{
+        guint n_pages = gxps_document_get_n_pages (document);
+        guint retval = 0;
+
+        while (n_pages >= 10) {
+                n_pages /= 10;
+                retval++;
+        }
+
+        return retval + 1;
+}
+
+static void
+gxps_converter_image_converter_begin_document (GXPSConverter *converter,
+                                               const gchar   *output_filename,
+                                               GXPSPage      *first_page)
+{
+        GXPSImageConverter *image_converter = GXPS_IMAGE_CONVERTER (converter);
+
+        image_converter->page_prefix = g_strdup (output_filename ? output_filename : "page");
+        image_converter->n_digits = get_n_digits (converter->document);
+}
+
+static cairo_t *
+gxps_converter_image_converter_begin_page (GXPSConverter *converter,
+                                           GXPSPage      *page,
+                                           guint          n_page)
+{
+        GXPSImageConverter *image_converter = GXPS_IMAGE_CONVERTER (converter);
+        guint               page_width, page_height;
+        gdouble             output_width, output_height;
+        cairo_t            *cr;
+
+        g_return_val_if_fail (converter->surface == NULL, NULL);
+
+        image_converter->current_page = n_page;
+
+        gxps_page_get_size (page, &page_width, &page_height);
+        gxps_converter_get_crop_size (converter,
+                                      page_width * (converter->x_resolution / 96.0),
+                                      page_height * (converter->y_resolution / 96.0),
+                                      &output_width, &output_height);
+        converter->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+                                                         ceil (output_width),
+                                                         ceil (output_height));
+
+        cr = cairo_create (converter->surface);
+
+        if (image_converter->fill_background) {
+                cairo_save (cr);
+                cairo_set_source_rgb (cr, 1, 1, 1);
+                cairo_paint (cr);
+                cairo_restore (cr);
+        }
+
+        cairo_translate (cr, -converter->crop.x, -converter->crop.y);
+        cairo_scale (cr, converter->x_resolution / 96.0, converter->y_resolution / 96.0);
+
+        return cr;
+}
+
+static void
+gxps_converter_image_converter_end_page (GXPSConverter *converter)
+{
+        GXPSImageConverter *image_converter = GXPS_IMAGE_CONVERTER (converter);
+        cairo_status_t      status;
+        const gchar        *extension = gxps_converter_get_extension (converter);
+        gchar              *page_filename;
+        FILE               *fd;
+        guint               width, height;
+        gint                stride;
+        guchar             *data;
+        gint                y;
+
+        g_return_if_fail (converter->surface != NULL);
+        g_return_if_fail (GXPS_IS_IMAGE_WRITER (image_converter->writer));
+
+        width = cairo_image_surface_get_width (converter->surface);
+        height = cairo_image_surface_get_height (converter->surface);
+        stride = cairo_image_surface_get_stride (converter->surface);
+        data = cairo_image_surface_get_data (converter->surface);
+
+        page_filename = g_strdup_printf ("%s-%0*d.%s",
+                                         image_converter->page_prefix,
+                                         image_converter->n_digits,
+                                         image_converter->current_page,
+                                         extension);
+
+        fd = fopen (page_filename, "wb");
+        if (!fd) {
+                g_printerr ("Error opening output file %s\n", page_filename);
+                g_free (page_filename);
+
+                cairo_surface_destroy (converter->surface);
+                converter->surface = NULL;
+
+                return;
+        }
+        if (!gxps_image_writer_init (image_converter->writer, fd, width, height,
+                                     converter->x_resolution, converter->y_resolution)) {
+                g_printerr ("Error writing %s\n", page_filename);
+                g_free (page_filename);
+                fclose (fd);
+
+                cairo_surface_destroy (converter->surface);
+                converter->surface = NULL;
+
+                return;
+        }
+
+        for (y = 0; y < height; y++)
+                gxps_image_writer_write (image_converter->writer, data + y * stride);
+
+        gxps_image_writer_finish (image_converter->writer);
+        fclose (fd);
+        g_free (page_filename);
+
+        cairo_surface_finish (converter->surface);
+        status = cairo_surface_status (converter->surface);
+        if (status)
+                g_printerr ("Cairo error: %s\n", cairo_status_to_string (status));
+        cairo_surface_destroy (converter->surface);
+        converter->surface = NULL;
+}
+
+static void
+gxps_image_converter_finalize (GObject *object)
+{
+        GXPSImageConverter *converter = GXPS_IMAGE_CONVERTER (object);
+
+        if (converter->page_prefix) {
+                g_free (converter->page_prefix);
+                converter->page_prefix = NULL;
+        }
+
+        if (converter->writer) {
+                g_object_unref (converter->writer);
+                converter->writer = NULL;
+        }
+
+        G_OBJECT_CLASS (gxps_image_converter_parent_class)->finalize (object);
+}
+
+static void
+gxps_image_converter_init (GXPSImageConverter *converter)
+{
+        GXPSImageConverter *image_converter = GXPS_IMAGE_CONVERTER (converter);
+
+        image_converter->fill_background = TRUE;
+}
+
+static void
+gxps_image_converter_class_init (GXPSImageConverterClass *klass)
+{
+        GObjectClass       *object_class = G_OBJECT_CLASS (klass);
+        GXPSConverterClass *converter_class = GXPS_CONVERTER_CLASS (klass);
+
+        object_class->finalize = gxps_image_converter_finalize;
+
+        converter_class->begin_document = gxps_converter_image_converter_begin_document;
+        converter_class->begin_page = gxps_converter_image_converter_begin_page;
+        converter_class->end_page = gxps_converter_image_converter_end_page;
+}
+
diff --git a/tools/gxps-image-converter.h b/tools/gxps-image-converter.h
new file mode 100644
index 0000000..6f872d6
--- /dev/null
+++ b/tools/gxps-image-converter.h
@@ -0,0 +1,56 @@
+/* GXPSImageConverter
+ *
+ * Copyright (C) 2011  Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __GXPS_IMAGE_CONVERTER_H__
+#define __GXPS_IMAGE_CONVERTER_H__
+
+#include "gxps-converter.h"
+#include "gxps-image-writer.h"
+
+G_BEGIN_DECLS
+
+#define GXPS_TYPE_IMAGE_CONVERTER           (gxps_image_converter_get_type ())
+#define GXPS_IMAGE_CONVERTER(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GXPS_TYPE_IMAGE_CONVERTER, GXPSImageConverter))
+#define GXPS_IMAGE_CONVERTER_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GXPS_TYPE_IMAGE_CONVERTER, GXPSImageConverterClass))
+#define GXPS_IS_IMAGE_CONVERTER(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GXPS_TYPE_IMAGE_CONVERTER))
+#define GXPS_IS_IMAGE_CONVERTER_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, GXPS_TYPE_IMAGE_CONVERTER))
+#define GXPS_IMAGE_CONVERTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GXPS_TYPE_IMAGE_CONVERTER, GXPSImageConverterClass))
+
+typedef struct _GXPSImageConverter        GXPSImageConverter;
+typedef struct _GXPSImageConverterClass   GXPSImageConverterClass;
+
+struct _GXPSImageConverter {
+	GXPSConverter parent;
+
+        GXPSImageWriter *writer;
+        guint            current_page;
+        gchar           *page_prefix;
+        guint            n_digits;
+        guint            fill_background : 1;
+};
+
+struct _GXPSImageConverterClass {
+	GXPSConverterClass parent_class;
+};
+
+GType gxps_image_converter_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GXPS_IMAGE_CONVERTER_H__ */
diff --git a/tools/gxps-image-writer.c b/tools/gxps-image-writer.c
new file mode 100644
index 0000000..16ec3a3
--- /dev/null
+++ b/tools/gxps-image-writer.c
@@ -0,0 +1,61 @@
+/* GXPSImageWriter
+ *
+ * Copyright (C) 2011  Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <config.h>
+
+#include "gxps-image-writer.h"
+
+G_DEFINE_INTERFACE (GXPSImageWriter, gxps_image_writer, G_TYPE_OBJECT)
+
+static void
+gxps_image_writer_default_init (GXPSImageWriterInterface *iface)
+{
+}
+
+gboolean
+gxps_image_writer_init (GXPSImageWriter *image_writer,
+                        FILE            *fd,
+                        guint            width,
+                        guint            height,
+                        guint            x_resolution,
+                        guint            y_resolution)
+{
+        g_return_val_if_fail (GXPS_IS_IMAGE_WRITER (image_writer), FALSE);
+        g_return_val_if_fail (fd != NULL, FALSE);
+
+        return GXPS_IMAGE_WRITER_GET_IFACE (image_writer)->init (image_writer, fd, width, height,
+                                                                 x_resolution, y_resolution);
+}
+
+gboolean
+gxps_image_writer_write (GXPSImageWriter *image_writer,
+                         guchar          *row)
+{
+        g_return_val_if_fail (GXPS_IS_IMAGE_WRITER (image_writer), FALSE);
+
+        return GXPS_IMAGE_WRITER_GET_IFACE (image_writer)->write (image_writer, row);
+}
+
+gboolean
+gxps_image_writer_finish (GXPSImageWriter *image_writer)
+{
+        g_return_val_if_fail (GXPS_IS_IMAGE_WRITER (image_writer), FALSE);
+
+        return GXPS_IMAGE_WRITER_GET_IFACE (image_writer)->finish (image_writer);
+}
diff --git a/tools/gxps-image-writer.h b/tools/gxps-image-writer.h
new file mode 100644
index 0000000..f0815b2
--- /dev/null
+++ b/tools/gxps-image-writer.h
@@ -0,0 +1,64 @@
+/* GXPSImageWriter
+ *
+ * Copyright (C) 2011  Carlos Garcia Campos <carlosgc gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __GXPS_IMAGE_WRITER_H__
+#define __GXPS_IMAGE_WRITER_H__
+
+#include <stdio.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GXPS_TYPE_IMAGE_WRITER           (gxps_image_writer_get_type ())
+#define GXPS_IMAGE_WRITER(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GXPS_TYPE_IMAGE_WRITER, GXPSImageWriter))
+#define GXPS_IS_IMAGE_WRITER(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GXPS_TYPE_IMAGE_WRITER))
+#define GXPS_IMAGE_WRITER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GXPS_TYPE_IMAGE_WRITER, GXPSImageWriterInterface))
+
+typedef struct _GXPSImageWriter          GXPSImageWriter;
+typedef struct _GXPSImageWriterInterface GXPSImageWriterInterface;
+
+struct _GXPSImageWriterInterface {
+        GTypeInterface g_iface;
+
+        gboolean (* init)   (GXPSImageWriter *writer,
+                             FILE            *fd,
+                             guint            width,
+                             guint            height,
+                             guint            x_resolution,
+                             guint            y_resolution);
+        gboolean (* write)  (GXPSImageWriter *writer,
+                             guchar          *row);
+        gboolean (* finish) (GXPSImageWriter *writer);
+};
+
+GType    gxps_image_writer_get_type (void);
+
+gboolean gxps_image_writer_init     (GXPSImageWriter *image_writer,
+                                     FILE            *fd,
+                                     guint            width,
+                                     guint            height,
+                                     guint            x_resolution,
+                                     guint            y_resolution);
+gboolean gxps_image_writer_write    (GXPSImageWriter *image_writer,
+                                     guchar          *row);
+gboolean gxps_image_writer_finish   (GXPSImageWriter *image_writer);
+
+G_END_DECLS
+
+#endif /* __GXPS_IMAGE_WRITER_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]