[gthumb: 46/129] equalize tool: operate on the image_surface directly instead of converting to/from a GdkPixbuf
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb: 46/129] equalize tool: operate on the image_surface directly instead of converting to/from a GdkPixbuf
- Date: Wed, 27 Apr 2011 20:54:15 +0000 (UTC)
commit 7542cf265a6d27a41e03626b713bebaafddbc241
Author: Paolo Bacchilega <paobac src gnome org>
Date: Tue Apr 19 13:19:43 2011 +0200
equalize tool: operate on the image_surface directly instead of converting to/from a GdkPixbuf
extensions/file_tools/gth-file-tool-equalize.c | 162 ++++++++++++++++--------
1 files changed, 110 insertions(+), 52 deletions(-)
---
diff --git a/extensions/file_tools/gth-file-tool-equalize.c b/extensions/file_tools/gth-file-tool-equalize.c
index 6c12b1d..6468b07 100644
--- a/extensions/file_tools/gth-file-tool-equalize.c
+++ b/extensions/file_tools/gth-file-tool-equalize.c
@@ -27,9 +27,11 @@
typedef struct {
- GtkWidget *viewer_page;
- GthHistogram *histogram;
- int **part;
+ GtkWidget *viewer_page;
+ cairo_surface_t *source;
+ cairo_surface_t *destination;
+ GthHistogram *histogram;
+ int **part;
} EqualizeData;
@@ -75,19 +77,10 @@ equalize_histogram_setup (GthHistogram *hist,
static void
-equalize_init (GthPixbufTask *pixop)
+equalize_before (GthAsyncTask *task,
+ gpointer user_data)
{
- EqualizeData *data = pixop->data;
- int i;
-
- copy_source_to_destination (pixop);
- data->histogram = gth_histogram_new ();
- gth_histogram_calculate_for_pixbuf (data->histogram, pixop->src);
-
- data->part = g_new0 (int *, GTH_HISTOGRAM_N_CHANNELS);
- for (i = 0; i < GTH_HISTOGRAM_N_CHANNELS; i++)
- data->part[i] = g_new0 (int, 257);
- equalize_histogram_setup (data->histogram, data->part);
+ gth_task_progress (GTH_TASK (task), _("Equalizing image histogram"), NULL, TRUE, 0.0);
}
@@ -103,55 +96,123 @@ equalize_func (guchar u_value,
}
-static void
-equalize_step (GthPixbufTask *pixop)
+static gpointer
+equalize_exec (GthAsyncTask *task,
+ gpointer user_data)
{
- EqualizeData *data = pixop->data;
+ EqualizeData *equalize_data = user_data;
+ int i;
+ 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;
+
+ /* initialize the extra data */
+
+ equalize_data->histogram = gth_histogram_new ();
+ gth_histogram_calculate_for_image (equalize_data->histogram, equalize_data->source);
+
+ equalize_data->part = g_new0 (int *, GTH_HISTOGRAM_N_CHANNELS);
+ for (i = 0; i < GTH_HISTOGRAM_N_CHANNELS; i++)
+ equalize_data->part[i] = g_new0 (int, 257);
+ equalize_histogram_setup (equalize_data->histogram, equalize_data->part);
+
+ /* convert the image */
+
+ format = cairo_image_surface_get_format (equalize_data->source);
+ width = cairo_image_surface_get_width (equalize_data->source);
+ height = cairo_image_surface_get_height (equalize_data->source);
+ source_stride = cairo_image_surface_get_stride (equalize_data->source);
+
+ equalize_data->destination = cairo_image_surface_create (format, width, height);
+ destination_stride = cairo_image_surface_get_stride (equalize_data->destination);
+ p_source_line = cairo_image_surface_get_data (equalize_data->source);
+ p_destination_line = cairo_image_surface_get_data (equalize_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 = equalize_func (red, equalize_data->part, RED_PIX);
+ green = equalize_func (green, equalize_data->part, GREEN_PIX);
+ blue = equalize_func (blue, equalize_data->part, BLUE_PIX);
+ if (alpha != 0xff)
+ alpha = equalize_func (alpha, equalize_data->part, ALPHA_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] = equalize_func (pixop->src_pixel[RED_PIX], data->part, 0);
- pixop->dest_pixel[GREEN_PIX] = equalize_func (pixop->src_pixel[GREEN_PIX], data->part, 1);
- pixop->dest_pixel[BLUE_PIX] = equalize_func (pixop->src_pixel[BLUE_PIX], data->part, 2);
- if (pixop->has_alpha)
- pixop->dest_pixel[ALPHA_PIX] = equalize_func (pixop->src_pixel[ALPHA_PIX], data->part, 3);
+ terminated = TRUE;
+ gth_async_task_set_data (task, &terminated, NULL, NULL);
+
+ return NULL;
}
static void
-equalize_release (GthPixbufTask *pixop,
- GError *error)
+equalize_after (GthAsyncTask *task,
+ GError *error,
+ gpointer user_data)
{
- EqualizeData *data = pixop->data;
+ EqualizeData *equalize_data = user_data;
int i;
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 (equalize_data->viewer_page), equalize_data->destination, TRUE);
for (i = 0; i < GTH_HISTOGRAM_N_CHANNELS; i++)
- g_free (data->part[i]);
- g_free (data->part);
- g_object_unref (data->histogram);
+ g_free (equalize_data->part[i]);
+ g_free (equalize_data->part);
+ equalize_data->part = NULL;
+
+ g_object_unref (equalize_data->histogram);
+ equalize_data->histogram = NULL;
}
static void
equalize_destroy_data (gpointer user_data)
{
- EqualizeData *data = user_data;
+ EqualizeData *equalize_data = user_data;
- g_object_unref (data->viewer_page);
- g_free (data);
+ g_object_unref (equalize_data->viewer_page);
+ cairo_surface_destroy (equalize_data->destination);
+ cairo_surface_destroy (equalize_data->source);
+ g_free (equalize_data);
}
static void
gth_file_tool_equalize_activate (GthFileTool *base)
{
- GtkWidget *window;
- GtkWidget *viewer_page;
- GtkWidget *viewer;
- GdkPixbuf *src_pixbuf;
- EqualizeData *data;
- GthTask *task;
+ GtkWidget *window;
+ GtkWidget *viewer_page;
+ GtkWidget *viewer;
+ cairo_surface_t *image;
+ EqualizeData *equalize_data;
+ GthTask *task;
window = gth_file_tool_get_window (base);
viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
@@ -159,24 +220,21 @@ gth_file_tool_equalize_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 (EqualizeData, 1);
- data->viewer_page = g_object_ref (viewer_page);
- task = gth_pixbuf_task_new (_("Equalizing image histogram"),
- FALSE,
- equalize_init,
- equalize_step,
- equalize_release,
- data,
- equalize_destroy_data);
- gth_pixbuf_task_set_source (GTH_PIXBUF_TASK (task), src_pixbuf);
+ equalize_data = g_new0 (EqualizeData, 1);
+ equalize_data->viewer_page = g_object_ref (viewer_page);
+ equalize_data->source = cairo_surface_reference (image);
+ task = gth_async_task_new (equalize_before,
+ equalize_exec,
+ equalize_after,
+ equalize_data,
+ equalize_destroy_data);
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]