[gthumb: 41/129] desaturate tool: use the cairo_surface directly instead of converting to/from a GdkPixbuf
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb: 41/129] desaturate tool: use the cairo_surface directly instead of converting to/from a GdkPixbuf
- Date: Wed, 27 Apr 2011 20:53:49 +0000 (UTC)
commit 5b71aeefaf1aae80add957b2eb0a2a43af6d112f
Author: Paolo Bacchilega <paobac src gnome org>
Date: Mon Apr 18 22:11:22 2011 +0200
desaturate tool: use the cairo_surface directly instead of converting to/from a GdkPixbuf
extensions/file_tools/gth-file-tool-desaturate.c | 152 ++++++++++++++++------
1 files changed, 110 insertions(+), 42 deletions(-)
---
diff --git a/extensions/file_tools/gth-file-tool-desaturate.c b/extensions/file_tools/gth-file-tool-desaturate.c
index 724052b..3f27962 100644
--- a/extensions/file_tools/gth-file-tool-desaturate.c
+++ b/extensions/file_tools/gth-file-tool-desaturate.c
@@ -3,7 +3,7 @@
/*
* GThumb
*
- * Copyright (C) 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2011 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
@@ -25,6 +25,13 @@
#include "gth-file-tool-desaturate.h"
+typedef struct {
+ GtkWidget *viewer_page;
+ cairo_surface_t *source;
+ cairo_surface_t *destination;
+} DesaturateData;
+
+
static void
gth_file_tool_desaturate_update_sensitivity (GthFileTool *base)
{
@@ -41,51 +48,114 @@ gth_file_tool_desaturate_update_sensitivity (GthFileTool *base)
static void
-desaturate_step (GthPixbufTask *pixop)
+desaturate_data_free (gpointer user_data)
{
- guchar min, max, lightness;
-
- max = MAX (pixop->src_pixel[RED_PIX], pixop->src_pixel[GREEN_PIX]);
- max = MAX (max, pixop->src_pixel[BLUE_PIX]);
- min = MIN (pixop->src_pixel[RED_PIX], pixop->src_pixel[GREEN_PIX]);
- min = MIN (min, pixop->src_pixel[BLUE_PIX]);
- lightness = (max + min) / 2;
-
- pixop->dest_pixel[RED_PIX] = lightness;
- pixop->dest_pixel[GREEN_PIX] = lightness;
- pixop->dest_pixel[BLUE_PIX] = lightness;
+ DesaturateData *desaturate_data = user_data;
- if (pixop->has_alpha)
- pixop->dest_pixel[ALPHA_PIX] = pixop->src_pixel[ALPHA_PIX];
+ cairo_surface_destroy (desaturate_data->destination);
+ cairo_surface_destroy (desaturate_data->source);
+ g_free (desaturate_data);
}
static void
-task_completed_cb (GthTask *task,
- GError *error,
- gpointer user_data)
+desaturate_init (GthAsyncTask *task,
+ gpointer user_data)
{
- GthFileTool *base = user_data;
+ gth_task_progress (GTH_TASK (task), _("Applying changes"), NULL, TRUE, 0.0);
+}
- if (error == NULL) {
- GthPixbufTask *pixbuf_task;
- GtkWidget *viewer_page;
- pixbuf_task = GTH_PIXBUF_TASK (task);
- viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (gth_file_tool_get_window (base)));
- gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), pixbuf_task->dest, TRUE);
+static gpointer
+desaturate_exec (GthAsyncTask *task,
+ gpointer user_data)
+{
+ DesaturateData *desaturate_data = user_data;
+ cairo_format_t format;
+ int width;
+ int height;
+ int source_stride;
+ int destination_stride;
+ unsigned char *p_source_line;
+ unsigned char *p_destination_line;
+ unsigned char *p_source;
+ unsigned char *p_destination;
+ gboolean cancelled;
+ double progress;
+ gboolean terminated;
+ int x, y;
+ unsigned char red, green, blue, alpha;
+ unsigned char min, max, lightness;
+
+ format = cairo_image_surface_get_format (desaturate_data->source);
+ width = cairo_image_surface_get_width (desaturate_data->source);
+ height = cairo_image_surface_get_height (desaturate_data->source);
+ source_stride = cairo_image_surface_get_stride (desaturate_data->source);
+
+ desaturate_data->destination = cairo_image_surface_create (format, width, height);
+ destination_stride = cairo_image_surface_get_stride (desaturate_data->destination);
+ p_source_line = cairo_image_surface_get_data (desaturate_data->source);
+ p_destination_line = cairo_image_surface_get_data (desaturate_data->destination);
+ for (y = 0; y < height; y++) {
+ gth_async_task_get_data (task, NULL, &cancelled, NULL);
+ if (cancelled)
+ return NULL;
+
+ progress = (double) y / height;
+ gth_async_task_set_data (task, NULL, NULL, &progress);
+
+ p_source = p_source_line;
+ p_destination = p_destination_line;
+ for (x = 0; x < width; x++) {
+ CAIRO_GET_RGBA (p_source, red, green, blue, alpha);
+
+ max = MAX (MAX (red, green), blue);
+ min = MIN (MIN (red, green), blue);
+ lightness = (max + min) / 2;
+
+ CAIRO_SET_RGBA (p_destination,
+ lightness,
+ lightness,
+ lightness,
+ alpha);
+
+ p_source += 4;
+ p_destination += 4;
+ }
+ p_source_line += source_stride;
+ p_destination_line += destination_stride;
}
+
+ terminated = TRUE;
+ gth_async_task_set_data (task, &terminated, NULL, NULL);
+
+ return NULL;
+}
+
+
+static void
+desaturate_after (GthAsyncTask *task,
+ GError *error,
+ gpointer user_data)
+{
+ DesaturateData *desaturate_data = user_data;
+
+ if (error == NULL)
+ gth_image_viewer_page_set_image (GTH_IMAGE_VIEWER_PAGE (desaturate_data->viewer_page),
+ desaturate_data->destination,
+ TRUE);
}
static void
gth_file_tool_desaturate_activate (GthFileTool *base)
{
- GtkWidget *window;
- GtkWidget *viewer_page;
- GtkWidget *viewer;
- GdkPixbuf *src_pixbuf;
- GthTask *task;
+ GtkWidget *window;
+ GtkWidget *viewer_page;
+ GtkWidget *viewer;
+ cairo_surface_t *image;
+ DesaturateData *desaturate_data;
+ GthTask *task;
window = gth_file_tool_get_window (base);
viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
@@ -93,23 +163,21 @@ gth_file_tool_desaturate_activate (GthFileTool *base)
return;
viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page));
- src_pixbuf = gth_image_viewer_get_current_pixbuf (GTH_IMAGE_VIEWER (viewer));
- if (src_pixbuf == NULL)
+ image = gth_image_viewer_get_current_image (GTH_IMAGE_VIEWER (viewer));
+ if (image == NULL)
return;
- task = gth_pixbuf_task_new (_("Desaturating image"),
- FALSE,
- copy_source_to_destination,
- desaturate_step,
- NULL,
- NULL,
- NULL);
- gth_pixbuf_task_set_source (GTH_PIXBUF_TASK (task), src_pixbuf);
- g_signal_connect (task, "completed", G_CALLBACK (task_completed_cb), base);
+ desaturate_data = g_new0 (DesaturateData, 1);
+ desaturate_data->viewer_page = viewer_page;
+ desaturate_data->source = cairo_surface_reference (image);
+ task = gth_async_task_new (desaturate_init,
+ desaturate_exec,
+ desaturate_after,
+ desaturate_data,
+ desaturate_data_free);
gth_browser_exec_task (GTH_BROWSER (window), task, FALSE);
g_object_unref (task);
- g_object_unref (src_pixbuf);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]