/* Gnome Scan - Scan as easy as you print * Copyright © 2007 Étienne Bersac * * Gnome Scan 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. * * gnome-scan 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 gnome-scan. If not, write to: * * the Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301, USA */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "xap_App.h" #include "xap_Frame.h" #include "ie_imp_XHTML.h" #include "ut_bytebuf.h" #include "fv_View.h" #include "abiscan-sink.h" #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ABISCAN_TYPE_SINK, AbiscanSinkPrivate)) typedef struct _AbiscanSinkPrivate AbiscanSinkPrivate; struct _AbiscanSinkPrivate { GeglNode *root; GeglNode *load; GeglNode *output; GeglProcessor *processor; gboolean continue_work; }; static GnomeScanSinkClass* parent_class = NULL; static void as_configure (GnomeScanPlugin *plugin, GnomeScanSettings *settings); static gboolean as_start_frame (GnomeScanPlugin *plugin); static gboolean as_work (GnomeScanPlugin *plugin, gdouble *progress); static void as_end_frame (GnomeScanPlugin *plugin); G_DEFINE_TYPE (AbiscanSink, abiscan_sink, GNOME_TYPE_SCAN_SINK); static void abiscan_sink_init (AbiscanSink *object) { AbiscanSinkPrivate *priv = GET_PRIVATE (object); } static void abiscan_sink_finalize (GObject *object) { /* TODO: Add deinitalization code here */ G_OBJECT_CLASS (parent_class)->finalize (object); } static void abiscan_sink_class_init (AbiscanSinkClass *klass) { GObjectClass* object_class = G_OBJECT_CLASS (klass); parent_class = GNOME_SCAN_SINK_CLASS (g_type_class_peek_parent (klass)); GnomeScanPluginClass *plugin_class = GNOME_SCAN_PLUGIN_CLASS (klass); g_type_class_add_private (object_class, sizeof (AbiscanSinkPrivate)); plugin_class->configure = as_configure; plugin_class->start_frame = as_start_frame; plugin_class->work = as_work; plugin_class->end_frame = as_end_frame; object_class->finalize = abiscan_sink_finalize; } GnomeScanSink* abiscan_sink_new () { GObject *object = (GObject*) g_object_new (ABISCAN_TYPE_SINK, "name", "abiscan", "blurb", _("Import scan into AbiWord document"), NULL); return GNOME_SCAN_SINK (object); } /* INTERNALS */ static void as_configure (GnomeScanPlugin *plugin, GnomeScanSettings *settings) { AbiscanSink *sink = ABISCAN_SINK (plugin); AbiscanSinkPrivate *priv = GET_PRIVATE (sink); } static gboolean as_start_frame (GnomeScanPlugin *plugin) { AbiscanSink *sink = ABISCAN_SINK (plugin); AbiscanSinkPrivate *priv = GET_PRIVATE (sink); GeglNode *root, *load, *output; /* Gegl init */ root = gegl_node_new (); load = gegl_node_new_child (root, "operation", "load-buffer", "buffer", plugin->buffer, NULL); output = gegl_node_new_child (root, "operation", "png-save", "path", "/tmp/abiscan.png", "compression", 1, NULL); gegl_node_link_many (load, output, NULL); priv->processor = gegl_node_new_processor (output, NULL); priv->root = root; priv->load = load; priv->output = output; priv->continue_work = FALSE; return TRUE; } static gboolean as_work (GnomeScanPlugin *plugin, gdouble *progress) { AbiscanSinkPrivate *priv = GET_PRIVATE (plugin); priv->continue_work = gegl_processor_work (GET_PRIVATE (plugin)->processor, progress); *progress/=2.; if (!priv->continue_work) { guchar* output; gint exit_status; GError *error = NULL; // thanks Dominic Lachowicz if (g_spawn_command_line_sync("ocrocmd ocr /tmp/abiscan.png", (gchar**) &output, NULL, &exit_status, &error)) { XAP_App *app = XAP_App::getApp(); XAP_Frame *frame = app->getLastFocussedFrame(); // Thanks Martin Sevior FV_View *view = static_cast (frame->getCurrentView()); PD_Document *doc = static_cast (frame->getCurrentDoc()); PD_DocumentRange *range = new PD_DocumentRange(doc, view->getPoint(), view->getPoint()); IE_Imp_XHTML *imp = new IE_Imp_XHTML(doc); imp->pasteFromBuffer(range, output, strlen((const char*)output)); system("rm /tmp/abiscan.png"); g_free (output); } else { // TODO: error handling. g_debug (G_STRLOC ": OCR failed : %s", error->message); } *progress = 1.; } return priv->continue_work; } static void as_end_frame (GnomeScanPlugin *plugin) { AbiscanSinkPrivate *priv = GET_PRIVATE (plugin); #define destroy(t,o) g_object_unref(o); o = NULL; destroy ("processor", priv->processor); destroy ("load", priv->load); destroy ("output", priv->output); #define dbg_ref(t,o) g_debug("%s:%i %s %s:%i", __FUNCTION__, __LINE__, t, G_OBJECT_TYPE_NAME (o), G_OBJECT (o)->ref_count); g_object_unref (plugin->buffer); /* to unref one more time. Maybe a bug in GeglOp buffer ? */ #undef destroy }