[gthumb/ext] added "reg eye removal" tool
- From: Paolo Bacchilega <paobac src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gthumb/ext] added "reg eye removal" tool
- Date: Fri, 11 Sep 2009 20:18:16 +0000 (UTC)
commit 58db43a17310609a7bcd6c743a05b4ffd63198a1
Author: Paolo Bacchilega <paobac src gnome org>
Date: Fri Sep 11 19:56:55 2009 +0200
added "reg eye removal" tool
configure.ac | 3 +
extensions/Makefile.am | 1 +
extensions/comments/gth-comment.c | 19 +-
extensions/red_eye_removal/Makefile.am | 30 ++
extensions/red_eye_removal/data/Makefile.am | 2 +
extensions/red_eye_removal/data/ui/Makefile.am | 5 +
.../data/ui/red-eye-removal-options.ui | 191 ++++++++
extensions/red_eye_removal/gth-file-tool-red-eye.c | 502 ++++++++++++++++++++
extensions/red_eye_removal/gth-file-tool-red-eye.h | 54 +++
extensions/red_eye_removal/main.c | 53 ++
.../red_eye_removal.extension.in.in | 11 +
gthumb/gth-image-selector.c | 1 +
gthumb/gth-image-viewer.c | 2 +
gthumb/gth-sidebar.c | 6 +-
14 files changed, 870 insertions(+), 10 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 3e9481c..e536d0c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -274,6 +274,9 @@ extensions/list_tools/data/ui/Makefile
extensions/photo_importer/Makefile
extensions/photo_importer/data/Makefile
extensions/photo_importer/data/ui/Makefile
+extensions/red_eye_removal/Makefile
+extensions/red_eye_removal/data/Makefile
+extensions/red_eye_removal/data/ui/Makefile
extensions/rename_series/Makefile
extensions/rename_series/data/Makefile
extensions/rename_series/data/ui/Makefile
diff --git a/extensions/Makefile.am b/extensions/Makefile.am
index ada6456..4383bf1 100644
--- a/extensions/Makefile.am
+++ b/extensions/Makefile.am
@@ -9,6 +9,7 @@ SUBDIRS = \
image_viewer \
list_tools \
photo_importer \
+ red_eye_removal \
rename_series \
search \
slideshow
diff --git a/extensions/comments/gth-comment.c b/extensions/comments/gth-comment.c
index 8868f81..5fad0b5 100644
--- a/extensions/comments/gth-comment.c
+++ b/extensions/comments/gth-comment.c
@@ -165,13 +165,18 @@ gth_comment_real_load_from_element (DomDomizable *base,
else if (g_strcmp0 (node->tag_name, "Time") == 0)
gth_comment_set_time_from_time_t (self, atol (dom_element_get_inner_text (node)));
else if (g_strcmp0 (node->tag_name, "Keywords") == 0) {
- char **categories;
- int i;
-
- categories = g_strsplit (dom_element_get_inner_text (node), ",", -1);
- for (i = 0; categories[i] != NULL; i++)
- gth_comment_add_category (self, categories[i]);
- g_strfreev (categories);
+ const char *text;
+
+ text = dom_element_get_inner_text (node);
+ if (text != NULL) {
+ char **categories;
+ int i;
+
+ categories = g_strsplit (text, ",", -1);
+ for (i = 0; categories[i] != NULL; i++)
+ gth_comment_add_category (self, categories[i]);
+ g_strfreev (categories);
+ }
}
}
}
diff --git a/extensions/red_eye_removal/Makefile.am b/extensions/red_eye_removal/Makefile.am
new file mode 100644
index 0000000..16bb461
--- /dev/null
+++ b/extensions/red_eye_removal/Makefile.am
@@ -0,0 +1,30 @@
+SUBDIRS = data
+
+extensiondir = $(libdir)/gthumb-2.0/extensions
+extension_LTLIBRARIES = libred_eye_removal.la
+
+libred_eye_removal_la_SOURCES = \
+ gth-file-tool-red-eye.c \
+ gth-file-tool-red-eye.h \
+ main.c
+
+libred_eye_removal_la_CFLAGS = $(GTHUMB_CFLAGS) $(DISABLE_DEPRECATED) $(WARNINGS) -I$(top_srcdir) -I$(top_builddir)/gthumb
+libred_eye_removal_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
+libred_eye_removal_la_LIBADD = $(GTHUMB_LIBS)
+libred_eye_removal_la_DEPENDENCIES = $(top_builddir)/gthumb/gthumb$(EXEEXT)
+
+extensioninidir = $(extensiondir)
+extensionini_in_files = red_eye_removal.extension.in.in
+extensionini_DATA = $(extensionini_in_files:.extension.in.in=.extension)
+
+%.extension.in: %.extension.in.in $(extension_LTLIBRARIES)
+ sed -e "s|%LIBRARY%|`. ./$(extension_LTLIBRARIES) && echo $$dlname`|" \
+ $< > $@
+
+%.extension: %.extension.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
+
+EXTRA_DIST = $(extensionini_in_files)
+
+DISTCLEANFILES = $(extensionini_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/extensions/red_eye_removal/data/Makefile.am b/extensions/red_eye_removal/data/Makefile.am
new file mode 100644
index 0000000..4d5385d
--- /dev/null
+++ b/extensions/red_eye_removal/data/Makefile.am
@@ -0,0 +1,2 @@
+SUBDIRS = ui
+-include $(top_srcdir)/git.mk
diff --git a/extensions/red_eye_removal/data/ui/Makefile.am b/extensions/red_eye_removal/data/ui/Makefile.am
new file mode 100644
index 0000000..f34bb05
--- /dev/null
+++ b/extensions/red_eye_removal/data/ui/Makefile.am
@@ -0,0 +1,5 @@
+uidir = $(datadir)/gthumb-2.0/ui
+ui_DATA = red-eye-removal-options.ui
+EXTRA_DIST = $(ui_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/extensions/red_eye_removal/data/ui/red-eye-removal-options.ui b/extensions/red_eye_removal/data/ui/red-eye-removal-options.ui
new file mode 100644
index 0000000..f775e6d
--- /dev/null
+++ b/extensions/red_eye_removal/data/ui/red-eye-removal-options.ui
@@ -0,0 +1,191 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkAlignment" id="options">
+ <property name="visible">True</property>
+ <property name="top_padding">6</property>
+ <child>
+ <object class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame4">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment12">
+ <property name="visible">True</property>
+ <property name="top_padding">6</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkVBox" id="vbox10">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkTable" id="table2">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_X:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Y:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox5">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkSpinButton" id="x_spinbutton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="adjustment">x_adjustment</property>
+ <property name="climb_rate">1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox6">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkSpinButton" id="y_spinbutton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="adjustment">y_adjustment</property>
+ <property name="climb_rate">1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><b>Selection</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHSeparator" id="hseparator1">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="padding">6</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHButtonBox" id="hbuttonbox1">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <property name="layout_style">center</property>
+ <child>
+ <object class="GtkButton" id="cancel_button">
+ <property name="label">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">6</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkAdjustment" id="x_adjustment">
+ <property name="upper">10000</property>
+ <property name="step_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="y_adjustment">
+ <property name="upper">10000</property>
+ <property name="step_increment">1</property>
+ </object>
+</interface>
diff --git a/extensions/red_eye_removal/gth-file-tool-red-eye.c b/extensions/red_eye_removal/gth-file-tool-red-eye.c
new file mode 100644
index 0000000..a9e5b5c
--- /dev/null
+++ b/extensions/red_eye_removal/gth-file-tool-red-eye.c
@@ -0,0 +1,502 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <gthumb.h>
+#include <extensions/image_viewer/gth-image-viewer-page.h>
+#include "gth-file-tool-red-eye.h"
+
+
+#define GET_WIDGET(x) (_gtk_builder_get_widget (self->priv->builder, (x)))
+#define REGION_SEARCH_SIZE 3
+
+
+static const double RED_FACTOR = 0.5133333;
+static const double GREEN_FACTOR = 1.0;
+static const double BLUE_FACTOR = 0.1933333;
+static gpointer parent_class = NULL;
+
+
+struct _GthFileToolRedEyePrivate {
+ GdkPixbuf *src_pixbuf;
+ GtkBuilder *builder;
+ GthImageSelector *selector;
+ char *is_red;
+};
+
+
+static void
+gth_file_tool_red_eye_update_sensitivity (GthFileTool *base)
+{
+ GtkWidget *window;
+ GtkWidget *viewer_page;
+
+ window = gth_file_tool_get_window (base);
+ viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
+ if (! GTH_IS_IMAGE_VIEWER_PAGE (viewer_page))
+ gtk_widget_set_sensitive (GTK_WIDGET (base), FALSE);
+ else
+ gtk_widget_set_sensitive (GTK_WIDGET (base), TRUE);
+}
+
+
+static void
+cancel_button_clicked_cb (GtkButton *button,
+ GthFileToolRedEye *self)
+{
+ gth_file_tool_hide_options (GTH_FILE_TOOL (self));
+}
+
+
+static int
+find_region (int row,
+ int col,
+ int *rtop,
+ int *rbot,
+ int *rleft,
+ int *rright,
+ char *isred,
+ int width,
+ int height)
+{
+ int *rows, *cols, list_length = 0;
+ int mydir;
+ int total = 1;
+
+ /* a relatively efficient way to find all connected points in a
+ * region. It considers points that have isred == 1, sets them to 2
+ * if they are connected to the starting point.
+ * row and col are the starting point of the region,
+ * the next four params define a rectangle our region fits into.
+ * isred is an array that tells us if pixels are red or not.
+ */
+
+ *rtop = row;
+ *rbot = row;
+ *rleft = col;
+ *rright = col;
+
+ rows = g_malloc (width * height * sizeof(int));
+ cols = g_malloc (width * height * sizeof(int));
+
+ rows[0] = row;
+ cols[0] = col;
+ list_length = 1;
+
+ do {
+ list_length -= 1;
+ row = rows[list_length];
+ col = cols[list_length];
+ for (mydir = 0; mydir < 8 ; mydir++) {
+ switch (mydir) {
+ case 0:
+ /* going left */
+ if (col - 1 < 0) break;
+ if (isred[col-1+row*width] == 1) {
+ isred[col-1+row*width] = 2;
+ if (*rleft > col-1) *rleft = col-1;
+ rows[list_length] = row;
+ cols[list_length] = col-1;
+ list_length+=1;
+ total += 1;
+ }
+ break;
+ case 1:
+ /* up and left */
+ if (col - 1 < 0 || row -1 < 0 ) break;
+ if (isred[col-1+(row-1)*width] == 1 ) {
+ isred[col-1+(row-1)*width] = 2;
+ if (*rleft > col -1) *rleft = col-1;
+ if (*rtop > row -1) *rtop = row-1;
+ rows[list_length] = row-1;
+ cols[list_length] = col-1;
+ list_length += 1;
+ total += 1;
+ }
+ break;
+ case 2:
+ /* up */
+ if (row -1 < 0 ) break;
+ if (isred[col + (row-1)*width] == 1) {
+ isred[col + (row-1)*width] = 2;
+ if (*rtop > row-1) *rtop=row-1;
+ rows[list_length] = row-1;
+ cols[list_length] = col;
+ list_length +=1;
+ total += 1;
+ }
+ break;
+ case 3:
+ /* up and right */
+ if (col + 1 >= width || row -1 < 0 ) break;
+ if (isred[col+1+(row-1)*width] == 1) {
+ isred[col+1+(row-1)*width] = 2;
+ if (*rright < col +1) *rright = col+1;
+ if (*rtop > row -1) *rtop = row-1;
+ rows[list_length] = row-1;
+ cols[list_length] = col+1;
+ list_length += 1;
+ total +=1;
+ }
+ break;
+ case 4:
+ /* going right */
+ if (col + 1 >= width) break;
+ if (isred[col+1+row*width] == 1) {
+ isred[col+1+row*width] = 2;
+ if (*rright < col+1) *rright = col+1;
+ rows[list_length] = row;
+ cols[list_length] = col+1;
+ list_length += 1;
+ total += 1;
+ }
+ break;
+ case 5:
+ /* down and right */
+ if (col + 1 >= width || row +1 >= height ) break;
+ if (isred[col+1+(row+1)*width] ==1) {
+ isred[col+1+(row+1)*width] = 2;
+ if (*rright < col +1) *rright = col+1;
+ if (*rbot < row +1) *rbot = row+1;
+ rows[list_length] = row+1;
+ cols[list_length] = col+1;
+ list_length += 1;
+ total += 1;
+ }
+ break;
+ case 6:
+ /* down */
+ if (row +1 >= height ) break;
+ if (isred[col + (row+1)*width] == 1) {
+ isred[col + (row+1)*width] = 2;
+ if (*rbot < row+1) *rbot=row+1;
+ rows[list_length] = row+1;
+ cols[list_length] = col;
+ list_length += 1;
+ total += 1;
+ }
+ break;
+ case 7:
+ /* down and left */
+ if (col - 1 < 0 || row +1 >= height ) break;
+ if (isred[col-1+(row+1)*width] == 1) {
+ isred[col-1+(row+1)*width] = 2;
+ if (*rleft > col -1) *rleft = col-1;
+ if (*rbot < row +1) *rbot = row+1;
+ rows[list_length] = row+1;
+ cols[list_length] = col-1;
+ list_length += 1;
+ total += 1;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ while (list_length > 0); /* stop when we add no more */
+
+ g_free (rows);
+ g_free (cols);
+
+ return total;
+}
+
+
+static void
+init_is_red (GthFileToolRedEye *self,
+ GdkPixbuf *pixbuf)
+{
+ int width, height;
+ int rowstride, channels;
+ guchar *pixels;
+ int i, j;
+ int ad_red, ad_green, ad_blue;
+ const int THRESHOLD = 0;
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+ channels = gdk_pixbuf_get_n_channels (pixbuf);
+ pixels = gdk_pixbuf_get_pixels(pixbuf);
+
+ g_free (self->priv->is_red);
+ self->priv->is_red = g_new0 (char, width * height);
+
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
+ int ofs = channels * j + i * rowstride;
+
+ ad_red = pixels[ofs] * RED_FACTOR;
+ ad_green = pixels[ofs + 1] * GREEN_FACTOR;
+ ad_blue = pixels[ofs + 2] * BLUE_FACTOR;
+
+ // This test from the gimp redeye plugin.
+
+ if ((ad_red >= ad_green - THRESHOLD) && (ad_red >= ad_blue - THRESHOLD))
+ self->priv->is_red[j + i * width] = 1;
+ }
+ }
+}
+
+
+/* returns TRUE if the pixbuf has been modified */
+static gboolean
+fix_redeye (GdkPixbuf *pixbuf,
+ char *isred,
+ int x,
+ int y)
+{
+ gboolean region_fixed = FALSE;
+ int width;
+ int height;
+ int rowstride;
+ int channels;
+ guchar *pixels;
+ int search, i, j, ii, jj;
+ int ad_red, ad_blue, ad_green;
+ int rtop, rbot, rleft, rright; /* edges of region */
+ int num_pix;
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+ channels = gdk_pixbuf_get_n_channels (pixbuf);
+ pixels = gdk_pixbuf_get_pixels (pixbuf);
+
+ /*
+ * if isred is 0, we don't think the point is red, 1 means red, 2 means
+ * part of our region already.
+ */
+
+ for (search = 0; ! region_fixed && (search < REGION_SEARCH_SIZE); search++)
+ for (i = MAX (0, y - search); ! region_fixed && (i <= MIN (height - 1, y + search)); i++ )
+ for (j = MAX (0, x - search); ! region_fixed && (j <= MIN (width - 1, x + search)); j++) {
+ if (isred[j + i * width] == 0)
+ continue;
+
+ isred[j + i * width] = 2;
+
+ num_pix = find_region (i, j, &rtop, &rbot, &rleft, &rright, isred, width, height);
+
+ /* Fix the region. */
+ for (ii = rtop; ii <= rbot; ii++)
+ for (jj = rleft; jj <= rright; jj++)
+ if (isred[jj + ii * width] == 2) { /* Fix the pixel. */
+ int ofs;
+
+ ofs = channels*jj + ii*rowstride;
+ ad_red = pixels[ofs] * RED_FACTOR;
+ ad_green = pixels[ofs + 1] * GREEN_FACTOR;
+ ad_blue = pixels[ofs + 2] * BLUE_FACTOR;
+
+ pixels[ofs] = ((float) (ad_green + ad_blue)) / (2.0 * RED_FACTOR);
+
+ isred[jj + ii * width] = 0;
+ }
+
+ region_fixed = TRUE;
+ }
+
+ return region_fixed;
+}
+
+
+static void
+selector_selected_cb (GthImageSelector *selector,
+ int x,
+ int y,
+ GthFileToolRedEye *self)
+{
+ GtkWidget *window;
+ GtkWidget *viewer_page;
+ GdkPixbuf *old_pixbuf;
+ GdkPixbuf *new_pixbuf;
+
+ window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
+ viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
+
+ old_pixbuf = gth_image_viewer_page_get_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page));
+ new_pixbuf = gdk_pixbuf_copy (old_pixbuf);
+ init_is_red (self, new_pixbuf);
+ if (fix_redeye (new_pixbuf, self->priv->is_red, x, y)) {
+ gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), new_pixbuf);
+ gth_file_tool_hide_options (GTH_FILE_TOOL (self));
+ }
+
+ g_object_unref (new_pixbuf);
+}
+
+
+static void
+selector_motion_notify_cb (GthImageSelector *selector,
+ int x,
+ int y,
+ GthFileToolRedEye *self)
+{
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("x_spinbutton")), (double) x);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("y_spinbutton")), (double) y);
+}
+
+
+static GtkWidget *
+gth_file_tool_red_eye_get_options (GthFileTool *base)
+{
+ GthFileToolRedEye *self;
+ GtkWidget *window;
+ GtkWidget *viewer_page;
+ GtkWidget *viewer;
+ GtkWidget *options;
+
+ self = (GthFileToolRedEye *) base;
+
+ window = gth_file_tool_get_window (base);
+ viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
+ if (! GTH_IS_IMAGE_VIEWER_PAGE (viewer_page))
+ return NULL;
+
+ self->priv->builder = _gtk_builder_new_from_file ("red-eye-removal-options.ui", "red_eye_removal");
+ options = _gtk_builder_get_widget (self->priv->builder, "options");
+ gtk_widget_show (options);
+ g_signal_connect (GET_WIDGET ("cancel_button"),
+ "clicked",
+ G_CALLBACK (cancel_button_clicked_cb),
+ self);
+
+ viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page));
+ self->priv->selector = (GthImageSelector *) gth_image_selector_new (GTH_IMAGE_VIEWER (viewer), GTH_SELECTOR_TYPE_POINT);
+ gth_image_selector_set_mask_visible (self->priv->selector, FALSE);
+ g_signal_connect (self->priv->selector,
+ "selected",
+ G_CALLBACK (selector_selected_cb),
+ self);
+ g_signal_connect (self->priv->selector,
+ "motion_notify",
+ G_CALLBACK (selector_motion_notify_cb),
+ self);
+ gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), (GthImageViewerTool *) self->priv->selector);
+
+ return options;
+}
+
+
+static void
+gth_file_tool_red_eye_destroy_options (GthFileTool *base)
+{
+ GthFileToolRedEye *self;
+ GtkWidget *window;
+ GtkWidget *viewer_page;
+ GtkWidget *viewer;
+
+ self = (GthFileToolRedEye *) base;
+
+ window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
+ viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
+ viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page));
+ gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), NULL);
+
+ _g_object_unref (self->priv->builder);
+ _g_object_unref (self->priv->selector);
+ g_free (self->priv->is_red);
+
+ self->priv->builder = NULL;
+ self->priv->selector = NULL;
+ self->priv->is_red = NULL;
+}
+
+
+static void
+gth_file_tool_red_eye_activate (GthFileTool *base)
+{
+ gth_file_tool_show_options (base);
+}
+
+
+static void
+gth_file_tool_red_eye_instance_init (GthFileToolRedEye *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_FILE_TOOL_RED_EYE, GthFileToolRedEyePrivate);
+ self->priv->is_red = NULL;
+ gth_file_tool_construct (GTH_FILE_TOOL (self), GTK_STOCK_EDIT, _("Red Eye Removal"), _("Red Eye Removal"), FALSE);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self), _("Remove the red eye effect caused by camera flashes"));
+}
+
+
+static void
+gth_file_tool_red_eye_finalize (GObject *object)
+{
+ GthFileToolRedEye *self;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GTH_IS_FILE_TOOL_RED_EYE (object));
+
+ self = (GthFileToolRedEye *) object;
+
+ g_free (self->priv->is_red);
+ _g_object_unref (self->priv->selector);
+ _g_object_unref (self->priv->builder);
+
+ /* Chain up */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+gth_file_tool_red_eye_class_init (GthFileToolRedEyeClass *class)
+{
+ GObjectClass *gobject_class;
+ GthFileToolClass *file_tool_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (GthFileToolRedEyePrivate));
+
+ gobject_class = (GObjectClass*) class;
+ gobject_class->finalize = gth_file_tool_red_eye_finalize;
+
+ file_tool_class = (GthFileToolClass *) class;
+ file_tool_class->update_sensitivity = gth_file_tool_red_eye_update_sensitivity;
+ file_tool_class->activate = gth_file_tool_red_eye_activate;
+ file_tool_class->get_options = gth_file_tool_red_eye_get_options;
+ file_tool_class->destroy_options = gth_file_tool_red_eye_destroy_options;
+}
+
+
+GType
+gth_file_tool_red_eye_get_type (void) {
+ static GType type_id = 0;
+ if (type_id == 0) {
+ static const GTypeInfo g_define_type_info = {
+ sizeof (GthFileToolRedEyeClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gth_file_tool_red_eye_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (GthFileToolRedEye),
+ 0,
+ (GInstanceInitFunc) gth_file_tool_red_eye_instance_init,
+ NULL
+ };
+ type_id = g_type_register_static (GTH_TYPE_FILE_TOOL, "GthFileToolRedEye", &g_define_type_info, 0);
+ }
+ return type_id;
+}
diff --git a/extensions/red_eye_removal/gth-file-tool-red-eye.h b/extensions/red_eye_removal/gth-file-tool-red-eye.h
new file mode 100644
index 0000000..aa71615
--- /dev/null
+++ b/extensions/red_eye_removal/gth-file-tool-red-eye.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_FILE_TOOL_RED_EYE_H
+#define GTH_FILE_TOOL_RED_EYE_H
+
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_FILE_TOOL_RED_EYE (gth_file_tool_red_eye_get_type ())
+#define GTH_FILE_TOOL_RED_EYE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_FILE_TOOL_RED_EYE, GthFileToolRedEye))
+#define GTH_FILE_TOOL_RED_EYE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_FILE_TOOL_RED_EYE, GthFileToolRedEyeClass))
+#define GTH_IS_FILE_TOOL_RED_EYE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_FILE_TOOL_RED_EYE))
+#define GTH_IS_FILE_TOOL_RED_EYE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_FILE_TOOL_RED_EYE))
+#define GTH_FILE_TOOL_RED_EYE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTH_TYPE_FILE_TOOL_RED_EYE, GthFileToolRedEyeClass))
+
+typedef struct _GthFileToolRedEye GthFileToolRedEye;
+typedef struct _GthFileToolRedEyeClass GthFileToolRedEyeClass;
+typedef struct _GthFileToolRedEyePrivate GthFileToolRedEyePrivate;
+
+struct _GthFileToolRedEye {
+ GthFileTool parent_instance;
+ GthFileToolRedEyePrivate *priv;
+};
+
+struct _GthFileToolRedEyeClass {
+ GthFileToolClass parent_class;
+};
+
+GType gth_file_tool_red_eye_get_type (void);
+
+G_END_DECLS
+
+#endif /* GTH_FILE_TOOL_RED_EYE_H */
diff --git a/extensions/red_eye_removal/main.c b/extensions/red_eye_removal/main.c
new file mode 100644
index 0000000..3ff0fe5
--- /dev/null
+++ b/extensions/red_eye_removal/main.c
@@ -0,0 +1,53 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include <gthumb.h>
+#include "gth-file-tool-red-eye.h"
+
+
+G_MODULE_EXPORT void
+gthumb_extension_activate (void)
+{
+ gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_RED_EYE);
+}
+
+
+G_MODULE_EXPORT void
+gthumb_extension_deactivate (void)
+{
+}
+
+
+G_MODULE_EXPORT gboolean
+gthumb_extension_is_configurable (void)
+{
+ return FALSE;
+}
+
+
+G_MODULE_EXPORT void
+gthumb_extension_configure (GtkWindow *parent)
+{
+}
diff --git a/extensions/red_eye_removal/red_eye_removal.extension.in.in b/extensions/red_eye_removal/red_eye_removal.extension.in.in
new file mode 100644
index 0000000..d336e6b
--- /dev/null
+++ b/extensions/red_eye_removal/red_eye_removal.extension.in.in
@@ -0,0 +1,11 @@
+[Extension]
+_Name=Red-Eye Removal
+_Description=Tool to remove the red-eye effect from a photo.
+_Authors=gthumb development team
+Copyright=Copyright © 2009 The Free Software Foundation, Inc.
+Version=1.0
+
+[Loader]
+Type=module
+File=%LIBRARY%
+Requires=image_viewer;file_tools
diff --git a/gthumb/gth-image-selector.c b/gthumb/gth-image-selector.c
index 0fe16e0..d913fe0 100644
--- a/gthumb/gth-image-selector.c
+++ b/gthumb/gth-image-selector.c
@@ -1411,6 +1411,7 @@ gth_image_selector_new (GthImageViewer *viewer,
selector = g_object_new (GTH_TYPE_IMAGE_SELECTOR, NULL);
selector->priv->viewer = viewer;
+ selector->priv->type = type;
return GTH_IMAGE_VIEWER_TOOL (selector);
}
diff --git a/gthumb/gth-image-viewer.c b/gthumb/gth-image-viewer.c
index 1a4f97e..c96f81a 100644
--- a/gthumb/gth-image-viewer.c
+++ b/gthumb/gth-image-viewer.c
@@ -2029,6 +2029,8 @@ gth_image_viewer_set_pixbuf (GthImageViewer *viewer,
viewer->priv->is_void = (pixbuf == NULL);
gth_image_loader_set_pixbuf (viewer->priv->loader, pixbuf);
+ gth_image_viewer_tool_image_changed (viewer->priv->tool);
+
gth_image_viewer_update_view (viewer);
}
diff --git a/gthumb/gth-sidebar.c b/gthumb/gth-sidebar.c
index 99746ff..3aa966f 100644
--- a/gthumb/gth-sidebar.c
+++ b/gthumb/gth-sidebar.c
@@ -146,7 +146,7 @@ gth_sidebar_set_file (GthSidebar *sidebar,
GList *children;
GList *scan;
- gth_toolbox_deactivate_tool (GTH_TOOLBOX (sidebar->priv->toolbox));
+ /*gth_toolbox_deactivate_tool (GTH_TOOLBOX (sidebar->priv->toolbox)); FIXME */
children = gth_multipage_get_children (GTH_MULTIPAGE (sidebar->priv->properties));
for (scan = children; scan; scan = scan->next) {
@@ -165,8 +165,8 @@ gth_sidebar_set_file (GthSidebar *sidebar,
void
gth_sidebar_show_properties (GthSidebar *sidebar)
{
- if (gtk_notebook_get_current_page (GTK_NOTEBOOK (sidebar)) == GTH_SIDEBAR_PAGE_TOOLS)
- gth_toolbox_deactivate_tool (GTH_TOOLBOX (sidebar->priv->toolbox));
+ /*if (gtk_notebook_get_current_page (GTK_NOTEBOOK (sidebar)) == GTH_SIDEBAR_PAGE_TOOLS)
+ gth_toolbox_deactivate_tool (GTH_TOOLBOX (sidebar->priv->toolbox)); FIXME */
gtk_notebook_set_current_page (GTK_NOTEBOOK (sidebar), GTH_SIDEBAR_PAGE_PROPERTIES);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]