[gthumb/ext] [file tools] added the "adjust colors" tool
- From: Paolo Bacchilega <paobac src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gthumb/ext] [file tools] added the "adjust colors" tool
- Date: Sun, 13 Sep 2009 21:13:37 +0000 (UTC)
commit 4772c7542b8ab5ce9540256e9f42c8755cfa4e86
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sun Sep 13 10:03:35 2009 +0200
[file tools] added the "adjust colors" tool
extensions/file_tools/Makefile.am | 2 +
extensions/file_tools/data/ui/Makefile.am | 2 +-
.../file_tools/data/ui/adjust-colors-options.ui | 246 ++++++++
extensions/file_tools/data/ui/crop-options.ui | 4 +-
.../file_tools/gth-file-tool-adjust-colors.c | 622 ++++++++++++++++++++
.../file_tools/gth-file-tool-adjust-colors.h | 54 ++
extensions/file_tools/gth-file-tool-crop.c | 2 +-
extensions/file_tools/gth-file-tool-desaturate.c | 2 +-
extensions/file_tools/gth-file-tool-enhance.c | 10 +-
extensions/file_tools/gth-file-tool-equalize.c | 2 +-
extensions/file_tools/main.c | 6 +-
extensions/image_viewer/gth-image-viewer-page.c | 10 +-
extensions/image_viewer/gth-image-viewer-page.h | 3 +-
extensions/red_eye_removal/gth-file-tool-red-eye.c | 2 +-
gthumb/gth-pixbuf-task.c | 121 +++--
gthumb/gth-pixbuf-task.h | 11 +-
gthumb/gth-sidebar.c | 7 +-
17 files changed, 1024 insertions(+), 82 deletions(-)
---
diff --git a/extensions/file_tools/Makefile.am b/extensions/file_tools/Makefile.am
index fbe3d19..4b2a25e 100644
--- a/extensions/file_tools/Makefile.am
+++ b/extensions/file_tools/Makefile.am
@@ -4,6 +4,8 @@ extensiondir = $(libdir)/gthumb-2.0/extensions
extension_LTLIBRARIES = libfile_tools.la
libfile_tools_la_SOURCES = \
+ gth-file-tool-adjust-colors.c \
+ gth-file-tool-adjust-colors.h \
gth-file-tool-crop.c \
gth-file-tool-crop.h \
gth-file-tool-desaturate.c \
diff --git a/extensions/file_tools/data/ui/Makefile.am b/extensions/file_tools/data/ui/Makefile.am
index d3fd8dd..2fab922 100644
--- a/extensions/file_tools/data/ui/Makefile.am
+++ b/extensions/file_tools/data/ui/Makefile.am
@@ -1,5 +1,5 @@
uidir = $(datadir)/gthumb-2.0/ui
-ui_DATA = crop-options.ui
+ui_DATA = adjust-colors-options.ui crop-options.ui
EXTRA_DIST = $(ui_DATA)
-include $(top_srcdir)/git.mk
diff --git a/extensions/file_tools/data/ui/adjust-colors-options.ui b/extensions/file_tools/data/ui/adjust-colors-options.ui
new file mode 100644
index 0000000..4d6e8d2
--- /dev/null
+++ b/extensions/file_tools/data/ui/adjust-colors-options.ui
@@ -0,0 +1,246 @@
+<?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="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="n_rows">5</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Brightness:</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>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Con_trast:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Saturation:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="brightness_hbox">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </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>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="contrast_hbox">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="saturation_hbox">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hue_hbox">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Hue:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="gamma_hbox">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Intensity:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <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="ok_button">
+ <property name="label">gtk-apply</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">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>
+ <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">1</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="ratio_w_adjustment">
+ <property name="upper">9999</property>
+ <property name="step_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="crop_x_adjustment">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="crop_y_adjustment">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="crop_width_adjustment">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="crop_height_adjustment">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="ratio_h_adjustment">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ </object>
+</interface>
diff --git a/extensions/file_tools/data/ui/crop-options.ui b/extensions/file_tools/data/ui/crop-options.ui
index 236d0aa..1fd616b 100644
--- a/extensions/file_tools/data/ui/crop-options.ui
+++ b/extensions/file_tools/data/ui/crop-options.ui
@@ -363,7 +363,7 @@
</child>
<child>
<object class="GtkButton" id="cancel_button">
- <property name="label" translatable="yes">gtk-cancel</property>
+ <property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@@ -387,7 +387,7 @@
</child>
</object>
<object class="GtkAdjustment" id="ratio_w_adjustment">
- <property name="upper">9999</property>
+ <property name="upper">99999</property>
<property name="step_increment">1</property>
</object>
<object class="GtkAdjustment" id="crop_x_adjustment">
diff --git a/extensions/file_tools/gth-file-tool-adjust-colors.c b/extensions/file_tools/gth-file-tool-adjust-colors.c
new file mode 100644
index 0000000..03f632e
--- /dev/null
+++ b/extensions/file_tools/gth-file-tool-adjust-colors.c
@@ -0,0 +1,622 @@
+/* -*- 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 <math.h>
+#include <gthumb.h>
+#include <extensions/image_viewer/gth-image-viewer-page.h>
+#include "gth-file-tool-adjust-colors.h"
+
+
+#define GET_WIDGET(x) (_gtk_builder_get_widget (self->priv->builder, (x)))
+#define APPLY_DELAY 250
+
+
+static gpointer parent_class = NULL;
+
+
+struct _GthFileToolAdjustColorsPrivate {
+ GdkPixbuf *src_pixbuf;
+ GdkPixbuf *dest_pixbuf;
+ GtkBuilder *builder;
+ GtkAdjustment *brightness_adj;
+ GtkAdjustment *contrast_adj;
+ GtkAdjustment *saturation_adj;
+ GtkAdjustment *gamma_adj;
+ GthTask *pixbuf_task;
+ guint apply_event;
+};
+
+
+typedef struct {
+ double gamma[5];
+ int low_input[5];
+ int high_input[5];
+ int low_output[5];
+ int high_output[5];
+} Levels;
+
+
+
+typedef struct {
+ GtkWidget *viewer_page;
+ Levels levels;
+ double gamma;
+ double brightness;
+ double contrast;
+ double saturation;
+} AdjustData;
+
+
+static void
+levels_init (Levels *levels,
+ double brightness,
+ double contrast,
+ double gamma)
+{
+ int channel;
+ double slant;
+ double value;
+
+ for (channel = 0; channel < MAX_N_CHANNELS + 1; channel++) {
+ levels->gamma[channel] = 1.0;
+ levels->low_input[channel] = 0;
+ levels->high_input[channel] = 255;
+ levels->low_output[channel] = 0;
+ levels->high_output[channel] = 255;
+ }
+
+ /* */
+
+ levels->gamma[0] = pow (10, - (gamma / 100.0));
+
+ brightness = brightness / 127.0 / 2.0;
+ contrast = contrast / 127.0;
+
+ slant = tan ((contrast + 1) * G_PI_4);
+ if (brightness >= 0) {
+ value = -0.5 * slant + brightness * slant + 0.5;
+ if (value < 0.0) {
+ value = 0.0;
+
+ /* this slightly convoluted math follows by inverting the
+ * calculation of the brightness/contrast LUT in base/lut-funcs.h */
+
+ levels->low_input[0] = 255.0 * (- brightness * slant + 0.5 * slant - 0.5) / (slant - brightness * slant);
+ }
+
+ levels->low_output[0] = 255.0 * value;
+
+ value = 0.5 * slant + 0.5;
+ if (value > 1.0) {
+ value = 1.0;
+ levels->high_input[0] = 255.0 * (- brightness * slant + 0.5 * slant + 0.5) / (slant - brightness * slant);
+ }
+
+ levels->high_output[0] = 255.0 * value;
+ }
+ else {
+ value = 0.5 - 0.5 * slant;
+ if (value < 0.0) {
+ value = 0.0;
+ levels->low_input[0] = 255.0 * (0.5 * slant - 0.5) / (slant + brightness * slant);
+ }
+
+ levels->low_output[0] = 255.0 * value;
+
+ value = slant * brightness + slant * 0.5 + 0.5;
+ if (value > 1.0) {
+ value = 1.0;
+ levels->high_input[0] = 255.0 * (0.5 * slant + 0.5) / (slant + brightness * slant);
+ }
+
+ levels->high_output[0] = 255.0 * value;
+ }
+}
+
+
+static void
+adjust_colors_init (GthPixbufTask *pixop)
+{
+ /* AdjustData *data = pixop->data; FIXME: delte if not used */
+}
+
+
+static guchar
+adjust_levels_func (guchar value,
+ Levels *levels,
+ guchar lightness,
+ double saturation,
+ int channel)
+{
+ double inten;
+ int j;
+
+ inten = value;
+
+ /* For color images this runs through the loop with j = channel + 1
+ * the first time and j = 0 the second time
+ *
+ * For bw images this runs through the loop with j = 0 the first and
+ * only time
+ */
+ for (j = channel + 1; j >= 0; j -= (channel + 1)) {
+ inten /= 255.0;
+
+ /* determine input intensity */
+
+ if (levels->high_input[j] != levels->low_input[j])
+ inten = (255.0 * inten - levels->low_input[j]) /
+ (levels->high_input[j] - levels->low_input[j]);
+ else
+ inten = 255.0 * inten - levels->low_input[j];
+
+ if (levels->gamma[j] != 0.0) {
+ if (inten >= 0.0)
+ inten = pow ( inten, (1.0 / levels->gamma[j]));
+ else
+ inten = -pow (-inten, (1.0 / levels->gamma[j]));
+ }
+
+ inten = (saturation * lightness) + ((1.0 - saturation) * inten);
+
+ /* determine the output intensity */
+
+ if (levels->high_output[j] >= levels->low_output[j])
+ inten = inten * (levels->high_output[j] - levels->low_output[j]) +
+ levels->low_output[j];
+ else if (levels->high_output[j] < levels->low_output[j])
+ inten = levels->low_output[j] - inten *
+ (levels->low_output[j] - levels->high_output[j]);
+ }
+
+ if (inten < 0.0)
+ inten = 0.0;
+ else if (inten > 255.0)
+ inten = 255.0;
+
+ return (guchar) inten;
+}
+
+
+static guchar
+interpolate_value (guchar original,
+ guchar reference,
+ double distance)
+{
+ return CLAMP((distance * reference) + ((1.0 - distance) * original), 0, 255);
+}
+
+
+static guchar
+gamma_correction (guchar original,
+ double gamma)
+{
+ double inten;
+
+ inten = (double) original / 255.0;
+
+ if (gamma != 0.0) {
+ if (inten >= 0.0)
+ inten = pow ( inten, (1.0 / gamma));
+ else
+ inten = -pow (-inten, (1.0 / gamma));
+ }
+
+ return CLAMP (inten * 255.0, 0, 255);
+}
+
+
+static void
+adjust_colors_step (GthPixbufTask *pixop)
+{
+ AdjustData *data = pixop->data;
+ guchar min, max, lightness;
+
+ pixop->dest_pixel[RED_PIX] = pixop->src_pixel[RED_PIX];
+ pixop->dest_pixel[GREEN_PIX] = pixop->src_pixel[GREEN_PIX];
+ pixop->dest_pixel[BLUE_PIX] = pixop->src_pixel[BLUE_PIX];
+ if (pixop->has_alpha)
+ pixop->dest_pixel[ALPHA_PIX] = pixop->src_pixel[ALPHA_PIX];
+
+ /* intensitiy / gamma correction */
+
+ pixop->dest_pixel[RED_PIX] = gamma_correction (pixop->dest_pixel[RED_PIX], data->gamma);
+ pixop->dest_pixel[GREEN_PIX] = gamma_correction (pixop->dest_pixel[GREEN_PIX], data->gamma);
+ pixop->dest_pixel[BLUE_PIX] = gamma_correction (pixop->dest_pixel[BLUE_PIX], data->gamma);
+
+ /* brightness */
+
+ pixop->dest_pixel[RED_PIX] = interpolate_value (pixop->dest_pixel[RED_PIX], 0, data->brightness);
+ pixop->dest_pixel[GREEN_PIX] = interpolate_value (pixop->dest_pixel[GREEN_PIX], 0, data->brightness);
+ pixop->dest_pixel[BLUE_PIX] = interpolate_value (pixop->dest_pixel[BLUE_PIX], 0, data->brightness);
+
+ /* contrast */
+
+ pixop->dest_pixel[RED_PIX] = interpolate_value (pixop->dest_pixel[RED_PIX], 127, data->contrast);
+ pixop->dest_pixel[GREEN_PIX] = interpolate_value (pixop->dest_pixel[GREEN_PIX], 127, data->contrast);
+ pixop->dest_pixel[BLUE_PIX] = interpolate_value (pixop->dest_pixel[BLUE_PIX], 127, data->contrast);
+
+ /* saturation */
+
+ max = MAX (pixop->dest_pixel[RED_PIX], pixop->dest_pixel[GREEN_PIX]);
+ max = MAX (max, pixop->dest_pixel[BLUE_PIX]);
+ min = MIN (pixop->dest_pixel[RED_PIX], pixop->dest_pixel[GREEN_PIX]);
+ min = MIN (min, pixop->dest_pixel[BLUE_PIX]);
+ lightness = (max + min) / 2;
+
+ pixop->dest_pixel[RED_PIX] = interpolate_value (pixop->dest_pixel[RED_PIX], lightness, data->saturation);
+ pixop->dest_pixel[GREEN_PIX] = interpolate_value (pixop->dest_pixel[GREEN_PIX], lightness, data->saturation);
+ pixop->dest_pixel[BLUE_PIX] = interpolate_value (pixop->dest_pixel[BLUE_PIX], lightness, data->saturation);
+
+ /*pixop->dest_pixel[RED_PIX] = adjust_levels_func (pixop->src_pixel[RED_PIX], &data->levels, lightness, data->saturation, RED_PIX);
+ pixop->dest_pixel[GREEN_PIX] = adjust_levels_func (pixop->src_pixel[GREEN_PIX], &data->levels, lightness, data->saturation, GREEN_PIX);
+ pixop->dest_pixel[BLUE_PIX] = adjust_levels_func (pixop->src_pixel[BLUE_PIX], &data->levels, lightness, data->saturation, BLUE_PIX);
+ if (pixop->has_alpha)
+ pixop->dest_pixel[ALPHA_PIX] = pixop->src_pixel[ALPHA_PIX];*/
+}
+
+
+static void
+adjust_colors_release (GthPixbufTask *pixop,
+ GError *error)
+{
+ AdjustData *data = pixop->data;
+
+ if (error == NULL)
+ gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (data->viewer_page), pixop->dest, TRUE);
+
+ g_object_unref (data->viewer_page);
+ g_free (data);
+}
+
+
+static void
+gth_file_tool_adjust_colors_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
+ok_button_clicked_cb (GtkButton *button,
+ GthFileToolAdjustColors *self)
+{
+ GtkWidget *window;
+ GtkWidget *viewer_page;
+
+ window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
+ viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
+ gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), self->priv->dest_pixbuf, TRUE);
+ gth_file_tool_hide_options (GTH_FILE_TOOL (self));
+}
+
+
+static void
+cancel_button_clicked_cb (GtkButton *button,
+ GthFileToolAdjustColors *self)
+{
+ GtkWidget *window;
+ GthFileData *current_file;
+
+ if (self->priv->apply_event != 0) {
+ g_source_remove (self->priv->apply_event);
+ self->priv->apply_event = 0;
+ }
+
+ window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
+ current_file = gth_browser_get_current_file (GTH_BROWSER (window));
+ if (current_file != NULL) {
+ g_file_info_set_attribute_boolean (current_file->info, "gth::file::is-modified", FALSE);
+ gth_monitor_metadata_changed (gth_main_get_default_monitor (), current_file);
+ }
+
+ gth_file_tool_hide_options (GTH_FILE_TOOL (self));
+}
+
+
+static void
+task_completed_cb (GthTask *task,
+ GError *error,
+ GthFileToolAdjustColors *self)
+{
+ if (self->priv->pixbuf_task == task)
+ self->priv->pixbuf_task = NULL;
+ g_object_unref (task);
+
+ if (error == NULL) {
+ GtkWidget *window;
+ GtkWidget *viewer_page;
+
+ window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
+ viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
+ gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), self->priv->dest_pixbuf, FALSE);
+ }
+}
+
+
+static gboolean
+apply_cb (gpointer user_data)
+{
+ GthFileToolAdjustColors *self = user_data;
+ GtkWidget *window;
+ AdjustData *data;
+
+ if (self->priv->apply_event != 0) {
+ g_source_remove (self->priv->apply_event);
+ self->priv->apply_event = 0;
+ }
+
+ if (self->priv->pixbuf_task != NULL)
+ gth_task_cancel (self->priv->pixbuf_task);
+
+ window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
+
+ data = g_new0 (AdjustData, 1);
+ data->viewer_page = g_object_ref (gth_browser_get_viewer_page (GTH_BROWSER (window)));
+
+ levels_init (&data->levels,
+ gtk_adjustment_get_value (self->priv->brightness_adj),
+ gtk_adjustment_get_value (self->priv->contrast_adj),
+ gtk_adjustment_get_value (self->priv->gamma_adj));
+
+ data->gamma = pow (10, - (gtk_adjustment_get_value (self->priv->gamma_adj) / 100.0));
+ data->brightness = gtk_adjustment_get_value (self->priv->brightness_adj) / 100.0;
+ data->contrast = gtk_adjustment_get_value (self->priv->contrast_adj) / 100.0;
+ data->saturation = gtk_adjustment_get_value (self->priv->saturation_adj) / 100.0;
+
+ self->priv->pixbuf_task = gth_pixbuf_task_new (_("Applying changes"),
+ self->priv->src_pixbuf,
+ self->priv->dest_pixbuf,
+ adjust_colors_init,
+ adjust_colors_step,
+ adjust_colors_release,
+ data);
+ g_signal_connect (self->priv->pixbuf_task,
+ "completed",
+ G_CALLBACK (task_completed_cb),
+ self);
+
+ gth_browser_exec_task (GTH_BROWSER (window), self->priv->pixbuf_task, FALSE);
+
+ return FALSE;
+}
+
+
+static void
+value_changed_cb (GtkAdjustment *adj,
+ GthFileToolAdjustColors *self)
+{
+ if (self->priv->apply_event != 0) {
+ g_source_remove (self->priv->apply_event);
+ self->priv->apply_event = 0;
+ }
+ self->priv->apply_event = g_timeout_add (APPLY_DELAY, apply_cb, self);
+}
+
+
+static GtkAdjustment *
+gimp_scale_entry_new (GtkWidget *parent_box,
+ float value,
+ float lower,
+ float upper,
+ float step_increment,
+ float page_increment,
+ int digits)
+{
+ GtkWidget *hbox;
+ GtkWidget *scale;
+ GtkWidget *spinbutton;
+ GtkObject *adj;
+
+ adj = gtk_adjustment_new (value, lower, upper,
+ step_increment, page_increment,
+ 0.0);
+
+ spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1.0, 0);
+ gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinbutton), digits);
+ gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), 4);
+
+ scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));
+ gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
+ gtk_scale_set_digits (GTK_SCALE (scale), digits);
+
+ hbox = gtk_hbox_new (FALSE, 5);
+ gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), spinbutton, FALSE, FALSE, 0);
+
+ gtk_box_pack_start (GTK_BOX (parent_box), hbox, TRUE, TRUE, 0);
+ gtk_widget_show_all (hbox);
+
+ return (GtkAdjustment *) adj;
+}
+
+
+static GtkWidget *
+gth_file_tool_adjust_colors_get_options (GthFileTool *base)
+{
+ GthFileToolAdjustColors *self;
+ GtkWidget *window;
+ GtkWidget *viewer_page;
+ GtkWidget *viewer;
+ GtkWidget *options;
+
+ self = (GthFileToolAdjustColors *) 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;
+
+ _g_object_unref (self->priv->src_pixbuf);
+ _g_object_unref (self->priv->dest_pixbuf);
+
+ viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page));
+ self->priv->src_pixbuf = gth_image_viewer_get_current_pixbuf (GTH_IMAGE_VIEWER (viewer));
+ if (self->priv->src_pixbuf == NULL)
+ return NULL;
+
+ self->priv->src_pixbuf = g_object_ref (self->priv->src_pixbuf);
+ self->priv->dest_pixbuf = gdk_pixbuf_copy (self->priv->src_pixbuf);
+
+ self->priv->builder = _gtk_builder_new_from_file ("adjust-colors-options.ui", "file_tools");
+ options = _gtk_builder_get_widget (self->priv->builder, "options");
+ gtk_widget_show (options);
+
+ self->priv->brightness_adj = gimp_scale_entry_new (GET_WIDGET ("brightness_hbox"), 0.0, -100.0, 100.0, 1.0, 10.0, 0);
+ self->priv->contrast_adj = gimp_scale_entry_new (GET_WIDGET ("contrast_hbox"), 0.0, -100.0, 100.0, 1.0, 10.0, 0);
+ self->priv->gamma_adj = gimp_scale_entry_new (GET_WIDGET ("gamma_hbox"), 0.0, -100.0, 100.0, 1.0, 10.0, 0);
+ self->priv->saturation_adj = gimp_scale_entry_new (GET_WIDGET ("saturation_hbox"), 0.0, -100.0, 100.0, 1.0, 10.0, 0);
+
+ g_signal_connect (GET_WIDGET ("ok_button"),
+ "clicked",
+ G_CALLBACK (ok_button_clicked_cb),
+ self);
+ g_signal_connect (GET_WIDGET ("cancel_button"),
+ "clicked",
+ G_CALLBACK (cancel_button_clicked_cb),
+ self);
+ g_signal_connect (G_OBJECT (self->priv->brightness_adj),
+ "value-changed",
+ G_CALLBACK (value_changed_cb),
+ self);
+ g_signal_connect (G_OBJECT (self->priv->contrast_adj),
+ "value-changed",
+ G_CALLBACK (value_changed_cb),
+ self);
+ g_signal_connect (G_OBJECT (self->priv->gamma_adj),
+ "value-changed",
+ G_CALLBACK (value_changed_cb),
+ self);
+ g_signal_connect (G_OBJECT (self->priv->saturation_adj),
+ "value-changed",
+ G_CALLBACK (value_changed_cb),
+ self);
+
+ return options;
+}
+
+
+static void
+gth_file_tool_adjust_colors_destroy_options (GthFileTool *base)
+{
+ GthFileToolAdjustColors *self;
+
+ self = (GthFileToolAdjustColors *) base;
+
+ if (self->priv->apply_event != 0) {
+ g_source_remove (self->priv->apply_event);
+ self->priv->apply_event = 0;
+ }
+
+ _g_object_unref (self->priv->src_pixbuf);
+ _g_object_unref (self->priv->dest_pixbuf);
+ _g_object_unref (self->priv->builder);
+ self->priv->src_pixbuf = NULL;
+ self->priv->dest_pixbuf = NULL;
+ self->priv->builder = NULL;
+}
+
+
+static void
+gth_file_tool_adjust_colors_activate (GthFileTool *base)
+{
+ gth_file_tool_show_options (base);
+}
+
+
+static void
+gth_file_tool_adjust_colors_instance_init (GthFileToolAdjustColors *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_FILE_TOOL_ADJUST_COLORS, GthFileToolAdjustColorsPrivate);
+ gth_file_tool_construct (GTH_FILE_TOOL (self), GTK_STOCK_EDIT, _("Adjust Colors"), _("Adjust Colors"), TRUE);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self), _("Change brightness, contrast, saturation and gamma level of the image"));
+}
+
+
+static void
+gth_file_tool_adjust_colors_finalize (GObject *object)
+{
+ GthFileToolAdjustColors *self;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GTH_IS_FILE_TOOL_ADJUST_COLORS (object));
+
+ self = (GthFileToolAdjustColors *) object;
+
+ _g_object_unref (self->priv->src_pixbuf);
+ _g_object_unref (self->priv->dest_pixbuf);
+ _g_object_unref (self->priv->builder);
+
+ /* Chain up */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+gth_file_tool_adjust_colors_class_init (GthFileToolAdjustColorsClass *class)
+{
+ GObjectClass *gobject_class;
+ GthFileToolClass *file_tool_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (GthFileToolAdjustColorsPrivate));
+
+ gobject_class = (GObjectClass*) class;
+ gobject_class->finalize = gth_file_tool_adjust_colors_finalize;
+
+ file_tool_class = (GthFileToolClass *) class;
+ file_tool_class->update_sensitivity = gth_file_tool_adjust_colors_update_sensitivity;
+ file_tool_class->activate = gth_file_tool_adjust_colors_activate;
+ file_tool_class->get_options = gth_file_tool_adjust_colors_get_options;
+ file_tool_class->destroy_options = gth_file_tool_adjust_colors_destroy_options;
+}
+
+
+GType
+gth_file_tool_adjust_colors_get_type (void) {
+ static GType type_id = 0;
+ if (type_id == 0) {
+ static const GTypeInfo g_define_type_info = {
+ sizeof (GthFileToolAdjustColorsClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gth_file_tool_adjust_colors_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (GthFileToolAdjustColors),
+ 0,
+ (GInstanceInitFunc) gth_file_tool_adjust_colors_instance_init,
+ NULL
+ };
+ type_id = g_type_register_static (GTH_TYPE_FILE_TOOL, "GthFileToolAdjustColors", &g_define_type_info, 0);
+ }
+ return type_id;
+}
diff --git a/extensions/file_tools/gth-file-tool-adjust-colors.h b/extensions/file_tools/gth-file-tool-adjust-colors.h
new file mode 100644
index 0000000..1c2e4ee
--- /dev/null
+++ b/extensions/file_tools/gth-file-tool-adjust-colors.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_ADJUST_COLORS_H
+#define GTH_FILE_TOOL_ADJUST_COLORS_H
+
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_FILE_TOOL_ADJUST_COLORS (gth_file_tool_adjust_colors_get_type ())
+#define GTH_FILE_TOOL_ADJUST_COLORS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_FILE_TOOL_ADJUST_COLORS, GthFileToolAdjustColors))
+#define GTH_FILE_TOOL_ADJUST_COLORS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_FILE_TOOL_ADJUST_COLORS, GthFileToolAdjustColorsClass))
+#define GTH_IS_FILE_TOOL_ADJUST_COLORS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_FILE_TOOL_ADJUST_COLORS))
+#define GTH_IS_FILE_TOOL_ADJUST_COLORS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_FILE_TOOL_ADJUST_COLORS))
+#define GTH_FILE_TOOL_ADJUST_COLORS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTH_TYPE_FILE_TOOL_ADJUST_COLORS, GthFileToolAdjustColorsClass))
+
+typedef struct _GthFileToolAdjustColors GthFileToolAdjustColors;
+typedef struct _GthFileToolAdjustColorsClass GthFileToolAdjustColorsClass;
+typedef struct _GthFileToolAdjustColorsPrivate GthFileToolAdjustColorsPrivate;
+
+struct _GthFileToolAdjustColors {
+ GthFileTool parent_instance;
+ GthFileToolAdjustColorsPrivate *priv;
+};
+
+struct _GthFileToolAdjustColorsClass {
+ GthFileToolClass parent_class;
+};
+
+GType gth_file_tool_adjust_colors_get_type (void);
+
+G_END_DECLS
+
+#endif /* GTH_FILE_TOOL_ADJUST_COLORS_H */
diff --git a/extensions/file_tools/gth-file-tool-crop.c b/extensions/file_tools/gth-file-tool-crop.c
index 689c50f..6cb6974 100644
--- a/extensions/file_tools/gth-file-tool-crop.c
+++ b/extensions/file_tools/gth-file-tool-crop.c
@@ -106,7 +106,7 @@ crop_button_clicked_cb (GtkButton *button,
window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
- gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), new_pixbuf);
+ gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), new_pixbuf, TRUE);
gth_file_tool_hide_options (GTH_FILE_TOOL (self));
g_object_unref (new_pixbuf);
diff --git a/extensions/file_tools/gth-file-tool-desaturate.c b/extensions/file_tools/gth-file-tool-desaturate.c
index d639a24..b093f0b 100644
--- a/extensions/file_tools/gth-file-tool-desaturate.c
+++ b/extensions/file_tools/gth-file-tool-desaturate.c
@@ -68,7 +68,7 @@ desaturate_release (GthPixbufTask *pixop,
GError *error)
{
if (error == NULL)
- gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (pixop->data), pixop->dest);
+ gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (pixop->data), pixop->dest, TRUE);
}
diff --git a/extensions/file_tools/gth-file-tool-enhance.c b/extensions/file_tools/gth-file-tool-enhance.c
index bbd35fd..38e47ae 100644
--- a/extensions/file_tools/gth-file-tool-enhance.c
+++ b/extensions/file_tools/gth-file-tool-enhance.c
@@ -190,9 +190,9 @@ adjust_levels_step (GthPixbufTask *pixop)
{
EnhanceData *data = pixop->data;
- pixop->dest_pixel[RED_PIX] = levels_func (pixop->src_pixel[RED_PIX], data->levels, 0);
- pixop->dest_pixel[GREEN_PIX] = levels_func (pixop->src_pixel[GREEN_PIX], data->levels, 1);
- pixop->dest_pixel[BLUE_PIX] = levels_func (pixop->src_pixel[BLUE_PIX], data->levels, 2);
+ pixop->dest_pixel[RED_PIX] = levels_func (pixop->src_pixel[RED_PIX], data->levels, RED_PIX);
+ pixop->dest_pixel[GREEN_PIX] = levels_func (pixop->src_pixel[GREEN_PIX], data->levels, GREEN_PIX);
+ pixop->dest_pixel[BLUE_PIX] = levels_func (pixop->src_pixel[BLUE_PIX], data->levels, BLUE_PIX);
if (pixop->has_alpha)
pixop->dest_pixel[ALPHA_PIX] = pixop->src_pixel[ALPHA_PIX];
@@ -206,11 +206,11 @@ adjust_levels_release (GthPixbufTask *pixop,
EnhanceData *data = pixop->data;
if (error == NULL)
- gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (data->viewer_page), pixop->dest);
+ gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (data->viewer_page), pixop->dest, TRUE);
gth_histogram_free (data->hist);
g_free (data->levels);
- g_object_ref (data->viewer_page);
+ g_object_unref (data->viewer_page);
g_free (data);
}
diff --git a/extensions/file_tools/gth-file-tool-equalize.c b/extensions/file_tools/gth-file-tool-equalize.c
index edc43ff..395f20f 100644
--- a/extensions/file_tools/gth-file-tool-equalize.c
+++ b/extensions/file_tools/gth-file-tool-equalize.c
@@ -124,7 +124,7 @@ equalize_release (GthPixbufTask *pixop,
int i;
if (error == NULL)
- gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (data->viewer_page), pixop->dest);
+ gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (data->viewer_page), pixop->dest, TRUE);
for (i = 0; i < MAX_N_CHANNELS + 1; i++)
g_free (data->part[i]);
diff --git a/extensions/file_tools/main.c b/extensions/file_tools/main.c
index 8c3f75e..94d0c36 100644
--- a/extensions/file_tools/main.c
+++ b/extensions/file_tools/main.c
@@ -24,6 +24,7 @@
#include <config.h>
#include <gtk/gtk.h>
#include <gthumb.h>
+#include "gth-file-tool-adjust-colors.h"
#include "gth-file-tool-crop.h"
#include "gth-file-tool-desaturate.h"
#include "gth-file-tool-enhance.h"
@@ -41,10 +42,11 @@ gthumb_extension_activate (void)
gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_SAVE_AS);
gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_UNDO);
gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_REDO);
- gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_CROP);
- gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_DESATURATE);
+ gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_ADJUST_COLORS);
gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_ENHANCE);
gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_EQUALIZE);
+ gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_DESATURATE);
+ gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_CROP);
}
diff --git a/extensions/image_viewer/gth-image-viewer-page.c b/extensions/image_viewer/gth-image-viewer-page.c
index 0b3243d..5df5828 100644
--- a/extensions/image_viewer/gth-image-viewer-page.c
+++ b/extensions/image_viewer/gth-image-viewer-page.c
@@ -1144,11 +1144,13 @@ gth_image_viewer_page_get_pixbuf (GthImageViewerPage *self)
void
gth_image_viewer_page_set_pixbuf (GthImageViewerPage *self,
- GdkPixbuf *pixbuf)
+ GdkPixbuf *pixbuf,
+ gboolean add_to_history)
{
- gth_image_history_add_image (self->priv->history,
- gth_image_viewer_page_get_pixbuf (self),
- gth_browser_get_file_modified (GTH_BROWSER (self->priv->browser)));
+ if (add_to_history)
+ gth_image_history_add_image (self->priv->history,
+ gth_image_viewer_page_get_pixbuf (self),
+ gth_browser_get_file_modified (GTH_BROWSER (self->priv->browser)));
_gth_image_viewer_page_set_pixbuf (self, pixbuf, TRUE);
}
diff --git a/extensions/image_viewer/gth-image-viewer-page.h b/extensions/image_viewer/gth-image-viewer-page.h
index 2e6cda6..22a826b 100644
--- a/extensions/image_viewer/gth-image-viewer-page.h
+++ b/extensions/image_viewer/gth-image-viewer-page.h
@@ -51,7 +51,8 @@ GType gth_image_viewer_page_get_type (void);
GtkWidget * gth_image_viewer_page_get_image_viewer (GthImageViewerPage *page);
GdkPixbuf * gth_image_viewer_page_get_pixbuf (GthImageViewerPage *page);
void gth_image_viewer_page_set_pixbuf (GthImageViewerPage *page,
- GdkPixbuf *pixbuf);
+ GdkPixbuf *pixbuf,
+ gboolean add_to_history);
void gth_image_viewer_page_undo (GthImageViewerPage *page);
void gth_image_viewer_page_redo (GthImageViewerPage *page);
GthImageHistory * gth_image_viewer_page_get_history (GthImageViewerPage *self);
diff --git a/extensions/red_eye_removal/gth-file-tool-red-eye.c b/extensions/red_eye_removal/gth-file-tool-red-eye.c
index 3e73c5a..ef3cbea 100644
--- a/extensions/red_eye_removal/gth-file-tool-red-eye.c
+++ b/extensions/red_eye_removal/gth-file-tool-red-eye.c
@@ -339,7 +339,7 @@ selector_selected_cb (GthImageSelector *selector,
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_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), new_pixbuf, TRUE);
gth_file_tool_hide_options (GTH_FILE_TOOL (self));
}
diff --git a/gthumb/gth-pixbuf-task.c b/gthumb/gth-pixbuf-task.c
index 5bc537b..f95ba74 100644
--- a/gthumb/gth-pixbuf-task.c
+++ b/gthumb/gth-pixbuf-task.c
@@ -24,9 +24,7 @@
#include "gth-pixbuf-task.h"
-#define N_STEPS 20 /* number of lines to process in a single
- * timeout handler. */
-#define PROGRESS_STEP 5 /* notify progress each PROGRESS_STEP lines. */
+#define PROGRESS_DELAY 200 /* delay between progress notifications */
static gpointer parent_class = NULL;
@@ -55,34 +53,40 @@ gth_pixbuf_task_finalize (GObject *object)
g_return_if_fail (GTH_IS_PIXBUF_TASK (object));
pixbuf_task = GTH_PIXBUF_TASK (object);
- if (pixbuf_task->timeout_id != 0) {
- g_source_remove (pixbuf_task->timeout_id);
- pixbuf_task->timeout_id = 0;
+ if (pixbuf_task->progress_event != 0) {
+ g_source_remove (pixbuf_task->progress_event);
+ pixbuf_task->progress_event = 0;
}
+
release_pixbufs (pixbuf_task);
if (pixbuf_task->free_data_func != NULL)
(*pixbuf_task->free_data_func) (pixbuf_task);
+ g_mutex_free (pixbuf_task->data_mutex);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static gboolean
-one_step (gpointer data)
+update_progress (gpointer data)
{
GthPixbufTask *pixbuf_task = data;
- int dir = 1;
+ gboolean interrupt;
+ int line;
- if (! pixbuf_task->interrupt && pixbuf_task->single_step)
- (*pixbuf_task->step_func) (pixbuf_task);
+ g_mutex_lock (pixbuf_task->data_mutex);
+ interrupt = pixbuf_task->interrupt;
+ line = pixbuf_task->line;
+ g_mutex_unlock (pixbuf_task->data_mutex);
- if ((pixbuf_task->line >= pixbuf_task->height)
- || pixbuf_task->single_step
- || pixbuf_task->interrupt)
- {
+ if ((line >= pixbuf_task->height) || interrupt) {
GError *error = NULL;
- if (pixbuf_task->interrupt)
+ g_source_remove (pixbuf_task->progress_event);
+ pixbuf_task->progress_event = 0;
+
+ if (interrupt)
error = g_error_new_literal (GTH_TASK_ERROR, GTH_TASK_ERROR_CANCELLED, "");
if (pixbuf_task->release_func != NULL)
@@ -93,19 +97,37 @@ one_step (gpointer data)
return FALSE;
}
+ gth_task_progress (GTH_TASK (pixbuf_task),
+ pixbuf_task->description,
+ NULL,
+ FALSE,
+ (double) line / pixbuf_task->height);
+
+ return TRUE;
+}
+
+
+static gboolean
+execute_step (GthPixbufTask *pixbuf_task)
+{
+ int dir = 1;
+ gboolean interrupt;
+ int line;
+
+ g_mutex_lock (pixbuf_task->data_mutex);
+ interrupt = pixbuf_task->interrupt;
+ line = pixbuf_task->line;
+ g_mutex_unlock (pixbuf_task->data_mutex);
+
+ if ((line >= pixbuf_task->height) || interrupt)
+ return FALSE;
+
pixbuf_task->src_pixel = pixbuf_task->src_line;
pixbuf_task->src_line += pixbuf_task->rowstride;
pixbuf_task->dest_pixel = pixbuf_task->dest_line;
pixbuf_task->dest_line += pixbuf_task->rowstride;
- if (pixbuf_task->line % PROGRESS_STEP == 0)
- gth_task_progress (GTH_TASK (pixbuf_task),
- pixbuf_task->description,
- NULL,
- FALSE,
- (double) pixbuf_task->line / pixbuf_task->height);
-
if (! pixbuf_task->ltr) { /* right to left */
int ofs = (pixbuf_task->width - 1) * pixbuf_task->bytes_per_pixel;
pixbuf_task->src_pixel += ofs;
@@ -125,30 +147,29 @@ one_step (gpointer data)
pixbuf_task->line_step++;
}
+ g_mutex_lock (pixbuf_task->data_mutex);
pixbuf_task->line++;
+ g_mutex_unlock (pixbuf_task->data_mutex);
return TRUE;
}
-static gboolean
-step (gpointer data)
+static gpointer
+execute_task (gpointer user_data)
{
- GthPixbufTask *pixbuf_task = data;
- int i;
+ GthPixbufTask *pixbuf_task = user_data;
- if (pixbuf_task->timeout_id != 0) {
- g_source_remove (pixbuf_task->timeout_id);
- pixbuf_task->timeout_id = 0;
- }
+ g_mutex_lock (pixbuf_task->data_mutex);
+ pixbuf_task->line = 0;
+ g_mutex_unlock (pixbuf_task->data_mutex);
- for (i = 0; i < N_STEPS; i++)
- if (! one_step (data))
- return FALSE;
+ if (pixbuf_task->init_func != NULL)
+ (*pixbuf_task->init_func) (pixbuf_task);
- pixbuf_task->timeout_id = g_idle_add (step, pixbuf_task);
+ while (execute_step (pixbuf_task)) /* void */;
- return FALSE;
+ return NULL;
}
@@ -157,17 +178,12 @@ gth_pixbuf_task_exec (GthTask *task)
{
GthPixbufTask *pixbuf_task;
- g_return_if_fail (GTH_IS_PIXBUF_TASK (task));
-
pixbuf_task = GTH_PIXBUF_TASK (task);
g_return_if_fail (pixbuf_task->src != NULL);
- pixbuf_task->line = 0;
- if (pixbuf_task->init_func != NULL)
- (*pixbuf_task->init_func) (pixbuf_task);
-
- step (pixbuf_task);
+ g_thread_create (execute_task, pixbuf_task, FALSE, NULL);
+ pixbuf_task->progress_event = g_timeout_add (PROGRESS_DELAY, update_progress, pixbuf_task);
}
@@ -179,7 +195,10 @@ gth_pixbuf_task_cancel (GthTask *task)
g_return_if_fail (GTH_IS_PIXBUF_TASK (task));
pixbuf_task = GTH_PIXBUF_TASK (task);
+
+ g_mutex_lock (pixbuf_task->data_mutex);
pixbuf_task->interrupt = TRUE;
+ g_mutex_unlock (pixbuf_task->data_mutex);
}
@@ -219,9 +238,11 @@ gth_pixbuf_task_init (GthPixbufTask *pixbuf_task)
pixbuf_task->ltr = TRUE;
- pixbuf_task->timeout_id = 0;
+ pixbuf_task->progress_event = 0;
pixbuf_task->line = 0;
pixbuf_task->interrupt = FALSE;
+
+ pixbuf_task->data_mutex = g_mutex_new ();
}
@@ -279,17 +300,9 @@ gth_pixbuf_task_new (const char *description,
void
-gth_pixbuf_task_set_single_step (GthPixbufTask *pixbuf_task,
- gboolean single_step)
-{
- pixbuf_task->single_step = single_step;
-}
-
-
-void
-gth_pixbuf_task_set_pixbufs (GthPixbufTask *pixbuf_task,
- GdkPixbuf *src,
- GdkPixbuf *dest)
+gth_pixbuf_task_set_pixbufs (GthPixbufTask *pixbuf_task,
+ GdkPixbuf *src,
+ GdkPixbuf *dest)
{
if (src == NULL)
return;
diff --git a/gthumb/gth-pixbuf-task.h b/gthumb/gth-pixbuf-task.h
index e3b0d83..4f8d251 100644
--- a/gthumb/gth-pixbuf-task.h
+++ b/gthumb/gth-pixbuf-task.h
@@ -61,8 +61,6 @@ struct _GthPixbufTask {
PixbufDoneFunc release_func;
PixbufOpFunc free_data_func;
- gboolean single_step;
-
gboolean has_alpha;
int bytes_per_pixel;
int width, height;
@@ -71,13 +69,16 @@ struct _GthPixbufTask {
guchar *dest_line, *dest_pixel;
gboolean ltr, first_step, last_step;
- guint timeout_id;
int line;
int line_step;
int column;
gboolean interrupt;
-
const char *description;
+
+ /*< private >*/
+
+ GMutex *data_mutex;
+ guint progress_event;
};
struct _GthPixbufTaskClass {
@@ -92,8 +93,6 @@ GthTask * gth_pixbuf_task_new (const char *description,
PixbufOpFunc step_func,
PixbufDoneFunc release_func,
gpointer data);
-void gth_pixbuf_task_set_single_step (GthPixbufTask *pixbuf_task,
- gboolean single_step);
void gth_pixbuf_task_set_pixbufs (GthPixbufTask *pixbuf_task,
GdkPixbuf *src,
GdkPixbuf *dest);
diff --git a/gthumb/gth-sidebar.c b/gthumb/gth-sidebar.c
index e63d12d..8727875 100644
--- a/gthumb/gth-sidebar.c
+++ b/gthumb/gth-sidebar.c
@@ -146,7 +146,8 @@ gth_sidebar_set_file (GthSidebar *sidebar,
GList *children;
GList *scan;
- gth_toolbox_deactivate_tool (GTH_TOOLBOX (sidebar->priv->toolbox));
+ if (! g_file_info_get_attribute_boolean (file_data->info, "gth::file::is-modified"))
+ gth_toolbox_deactivate_tool (GTH_TOOLBOX (sidebar->priv->toolbox));
children = gth_multipage_get_children (GTH_MULTIPAGE (sidebar->priv->properties));
for (scan = children; scan; scan = scan->next) {
@@ -165,8 +166,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]