[gthumb: 44/129] enhance tool: operate on 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: 44/129] enhance tool: operate on the cairo_surface directly instead of converting to/from a GdkPixbuf
- Date: Wed, 27 Apr 2011 20:54:05 +0000 (UTC)
commit 6e6ec8d6dfd3363d284ffbfedc3dec5c271a9f21
Author: Paolo Bacchilega <paobac src gnome org>
Date: Tue Apr 19 12:50:53 2011 +0200
enhance tool: operate on the cairo_surface directly instead of converting to/from a GdkPixbuf
extensions/file_tools/gth-file-tool-enhance.c | 162 ++++++++++++++++---------
1 files changed, 106 insertions(+), 56 deletions(-)
---
diff --git a/extensions/file_tools/gth-file-tool-enhance.c b/extensions/file_tools/gth-file-tool-enhance.c
index ed2213f..2072a8c 100644
--- a/extensions/file_tools/gth-file-tool-enhance.c
+++ b/extensions/file_tools/gth-file-tool-enhance.c
@@ -36,9 +36,11 @@ typedef struct {
typedef struct {
- GtkWidget *viewer_page;
- GthHistogram *histogram;
- Levels *levels;
+ GtkWidget *viewer_page;
+ cairo_surface_t *source;
+ cairo_surface_t *destination;
+ GthHistogram *histogram;
+ Levels *levels;
} EnhanceData;
@@ -108,27 +110,29 @@ levels_channel_auto (Levels *levels,
static void
-adjust_levels_init (GthPixbufTask *pixop)
+enhance_before (GthAsyncTask *task,
+ gpointer user_data)
{
- EnhanceData *data = pixop->data;
+ EnhanceData *enhance_data = user_data;
int channel;
- copy_source_to_destination (pixop);
- data->histogram = gth_histogram_new ();
- gth_histogram_calculate_for_pixbuf (data->histogram, pixop->src);
+ gth_task_progress (GTH_TASK (task), _("White balance correction"), NULL, TRUE, 0.0);
- data->levels = g_new0 (Levels, 1);
+ enhance_data->histogram = gth_histogram_new ();
+ gth_histogram_calculate_for_image (enhance_data->histogram, enhance_data->source);
+
+ enhance_data->levels = g_new0 (Levels, 1);
for (channel = 0; channel < GTH_HISTOGRAM_N_CHANNELS; channel++) {
- data->levels->gamma[channel] = 1.0;
- data->levels->low_input[channel] = 0;
- data->levels->high_input[channel] = 255;
- data->levels->low_output[channel] = 0;
- data->levels->high_output[channel] = 255;
+ enhance_data->levels->gamma[channel] = 1.0;
+ enhance_data->levels->low_input[channel] = 0;
+ enhance_data->levels->high_input[channel] = 255;
+ enhance_data->levels->low_output[channel] = 0;
+ enhance_data->levels->high_output[channel] = 255;
}
for (channel = 1; channel < GTH_HISTOGRAM_N_CHANNELS - 1; channel++)
- levels_channel_auto (data->levels, data->histogram, channel);
+ levels_channel_auto (enhance_data->levels, enhance_data->histogram, channel);
}
@@ -185,55 +189,104 @@ levels_func (guchar value,
}
-static void
-adjust_levels_step (GthPixbufTask *pixop)
+static gpointer
+enhance_exec (GthAsyncTask *task,
+ gpointer user_data)
{
- EnhanceData *data = pixop->data;
+ EnhanceData *enhance_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;
+
+ format = cairo_image_surface_get_format (enhance_data->source);
+ width = cairo_image_surface_get_width (enhance_data->source);
+ height = cairo_image_surface_get_height (enhance_data->source);
+ source_stride = cairo_image_surface_get_stride (enhance_data->source);
+
+ enhance_data->destination = cairo_image_surface_create (format, width, height);
+ destination_stride = cairo_image_surface_get_stride (enhance_data->destination);
+ p_source_line = cairo_image_surface_get_data (enhance_data->source);
+ p_destination_line = cairo_image_surface_get_data (enhance_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);
+ red = levels_func (red, enhance_data->levels, RED_PIX);
+ green = levels_func (green, enhance_data->levels, GREEN_PIX);
+ blue = levels_func (blue, enhance_data->levels, BLUE_PIX);
+ CAIRO_SET_RGBA (p_destination, red, green, blue, alpha);
+
+ p_source += 4;
+ p_destination += 4;
+ }
+ p_source_line += source_stride;
+ p_destination_line += destination_stride;
+ }
- 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);
+ terminated = TRUE;
+ gth_async_task_set_data (task, &terminated, NULL, NULL);
- if (pixop->has_alpha)
- pixop->dest_pixel[ALPHA_PIX] = pixop->src_pixel[ALPHA_PIX];
+ return NULL;
}
static void
-adjust_levels_release (GthPixbufTask *pixop,
- GError *error)
+enhance_after (GthAsyncTask *task,
+ GError *error,
+ gpointer user_data)
{
- EnhanceData *data = pixop->data;
+ EnhanceData *enhance_data = user_data;
if (error == NULL)
- gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (data->viewer_page), pixop->dest, TRUE);
+ gth_image_viewer_page_set_image (GTH_IMAGE_VIEWER_PAGE (enhance_data->viewer_page), enhance_data->destination, TRUE);
- g_object_unref (data->histogram);
- data->histogram = NULL;
- g_free (data->levels);
- data->levels = NULL;
+ g_object_unref (enhance_data->histogram);
+ enhance_data->histogram = NULL;
+ g_free (enhance_data->levels);
+ enhance_data->levels = NULL;
}
static void
-adjust_levels_destroy_data (gpointer user_data)
+enhance_data_free (gpointer user_data)
{
- EnhanceData *data = user_data;
+ EnhanceData *enhance_data = user_data;
- g_object_unref (data->viewer_page);
- g_free (data);
+ g_object_unref (enhance_data->viewer_page);
+ cairo_surface_destroy (enhance_data->destination);
+ cairo_surface_destroy (enhance_data->source);
+ g_free (enhance_data);
}
static void
gth_file_tool_enhance_activate (GthFileTool *base)
{
- GtkWidget *window;
- GtkWidget *viewer_page;
- GtkWidget *viewer;
- GdkPixbuf *src_pixbuf;
- EnhanceData *data;
- GthTask *task;
+ GtkWidget *window;
+ GtkWidget *viewer_page;
+ GtkWidget *viewer;
+ cairo_surface_t *image;
+ EnhanceData *enhance_data;
+ GthTask *task;
window = gth_file_tool_get_window (base);
viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
@@ -241,26 +294,23 @@ gth_file_tool_enhance_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;
- data = g_new0 (EnhanceData, 1);
- data->viewer_page = g_object_ref (viewer_page);
- data->histogram = NULL;
- data->levels = NULL;
- task = gth_pixbuf_task_new (_("White balance correction"),
- FALSE,
- adjust_levels_init,
- adjust_levels_step,
- adjust_levels_release,
- data,
- adjust_levels_destroy_data);
- gth_pixbuf_task_set_source (GTH_PIXBUF_TASK (task), src_pixbuf);
+ enhance_data = g_new0 (EnhanceData, 1);
+ enhance_data->viewer_page = g_object_ref (viewer_page);
+ enhance_data->source = cairo_surface_reference (image);
+ enhance_data->histogram = NULL;
+ enhance_data->levels = NULL;
+ task = gth_async_task_new (enhance_before,
+ enhance_exec,
+ enhance_after,
+ enhance_data,
+ enhance_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]