[gthumb/ext] [file tools] added "enhance colors" command



commit 2f579e386f76ceb306d7986d000bc96b4baf5baf
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Fri Sep 11 12:20:36 2009 +0200

    [file tools] added "enhance colors" command

 extensions/file_tools/Makefile.am             |    2 +
 extensions/file_tools/gth-file-tool-enhance.c |  303 +++++++++++++++++++++++++
 extensions/file_tools/gth-file-tool-enhance.h |   52 +++++
 extensions/file_tools/main.c                  |    2 +
 gthumb/Makefile.am                            |    2 +
 gthumb/gth-histogram.c                        |  218 ++++++++++++++++++
 gthumb/gth-histogram.h                        |   57 +++++
 7 files changed, 636 insertions(+), 0 deletions(-)
---
diff --git a/extensions/file_tools/Makefile.am b/extensions/file_tools/Makefile.am
index d374dce..8cd7dee 100644
--- a/extensions/file_tools/Makefile.am
+++ b/extensions/file_tools/Makefile.am
@@ -8,6 +8,8 @@ libfile_tools_la_SOURCES = 		\
 	gth-file-tool-crop.h		\
 	gth-file-tool-desaturate.c	\
 	gth-file-tool-desaturate.h	\
+	gth-file-tool-enhance.c		\
+	gth-file-tool-enhance.h		\
 	gth-file-tool-redo.c		\
 	gth-file-tool-redo.h		\
 	gth-file-tool-save.c		\
diff --git a/extensions/file_tools/gth-file-tool-enhance.c b/extensions/file_tools/gth-file-tool-enhance.c
new file mode 100644
index 0000000..a29a610
--- /dev/null
+++ b/extensions/file_tools/gth-file-tool-enhance.c
@@ -0,0 +1,303 @@
+/* -*- 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-enhance.h"
+
+
+typedef struct {
+	double gamma[5];
+	double low_input[5];
+	double high_input[5];
+	double low_output[5];
+	double high_output[5];
+} Levels;
+
+
+typedef struct {
+	GtkWidget    *viewer_page;
+	GthHistogram *hist;
+	Levels       *levels;
+} EnhanceData;
+
+
+static void
+levels_channel_auto (Levels       *levels,
+		     GthHistogram *hist,
+		     int           channel)
+{
+	int    i;
+	double count, new_count, percentage, next_percentage;
+
+	g_return_if_fail (levels != NULL);
+	g_return_if_fail (hist != NULL);
+
+	levels->gamma[channel]       = 1.0;
+	levels->low_output[channel]  = 0;
+	levels->high_output[channel] = 255;
+
+	count = gth_histogram_get_count (hist, 0, 255);
+
+	if (count == 0.0) {
+		levels->low_input[channel]  = 0;
+		levels->high_input[channel] = 0;
+	}
+	else {
+		/*  Set the low input  */
+
+		new_count = 0.0;
+		for (i = 0; i < 255; i++) {
+			double value;
+			double next_value;
+
+			value = gth_histogram_get_value (hist, channel, i);
+			next_value = gth_histogram_get_value (hist, channel, i + 1);
+
+			new_count += value;
+			percentage = new_count / count;
+			next_percentage = (new_count + next_value) / count;
+
+			if (fabs (percentage - 0.006) < fabs (next_percentage - 0.006)) {
+				levels->low_input[channel] = i + 1;
+				break;
+			}
+		}
+
+		/*  Set the high input  */
+
+		new_count = 0.0;
+		for (i = 255; i > 0; i--) {
+			double value;
+			double next_value;
+
+			value = gth_histogram_get_value (hist, channel, i);
+			next_value = gth_histogram_get_value (hist, channel, i - 1);
+
+			new_count += value;
+			percentage = new_count / count;
+			next_percentage = (new_count + next_value) / count;
+
+			if (fabs (percentage - 0.006) < fabs (next_percentage - 0.006))	{
+				levels->high_input[channel] = i - 1;
+				break;
+			}
+		}
+	}
+}
+
+
+static void
+adjust_levels_init (GthPixbufTask *pixop)
+{
+	EnhanceData *data = pixop->data;
+	int          channel;
+
+	data->hist = gth_histogram_new ();
+	gth_histogram_calculate (data->hist, pixop->src);
+
+	data->levels = g_new0 (Levels, 1);
+
+	for (channel = 0; channel < MAX_N_CHANNELS + 1; 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;
+	}
+
+	for (channel = 1; channel < MAX_N_CHANNELS; channel++)
+		levels_channel_auto (data->levels, data->hist, channel);
+}
+
+
+static guchar
+levels_func (guchar  value,
+	     Levels *levels,
+	     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]));
+		}
+
+		/*  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 void
+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);
+
+	if (pixop->has_alpha)
+		pixop->dest_pixel[ALPHA_PIX] = pixop->src_pixel[ALPHA_PIX];
+}
+
+
+static void
+adjust_levels_release (GthPixbufTask *pixop)
+{
+	EnhanceData *data = pixop->data;
+
+	gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (data->viewer_page), pixop->dest);
+
+	gth_histogram_free (data->hist);
+	g_free (data->levels);
+	g_object_ref (data->viewer_page);
+	g_free (data);
+}
+
+
+static void
+gth_file_tool_enhance_activate (GthFileTool *base)
+{
+	GtkWidget   *window;
+	GtkWidget   *viewer_page;
+	GtkWidget   *viewer;
+	GdkPixbuf   *src_pixbuf;
+	GdkPixbuf   *dest_pixbuf;
+	EnhanceData *data;
+	GthTask     *task;
+
+	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;
+
+	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)
+		return;
+
+	dest_pixbuf = gdk_pixbuf_copy (src_pixbuf);
+	data = g_new0 (EnhanceData, 1);
+	data->viewer_page = g_object_ref (viewer_page);
+	task = gth_pixbuf_task_new (_("Enhancing image colors"),
+				    src_pixbuf,
+				    dest_pixbuf,
+				    adjust_levels_init,
+				    adjust_levels_step,
+				    adjust_levels_release,
+				    data);
+	gth_browser_exec_task (GTH_BROWSER (window), task, FALSE);
+
+	g_object_unref (task);
+	g_object_unref (dest_pixbuf);
+}
+
+
+static void
+gth_file_tool_enhance_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
+gth_file_tool_enhance_instance_init (GthFileToolEnhance *self)
+{
+	gth_file_tool_construct (GTH_FILE_TOOL (self), GTK_STOCK_EDIT /* FIXME GTH_STOCK_ENHANCE */, _("Enhance"), _("Enhance"));
+}
+
+
+static void
+gth_file_tool_enhance_class_init (GthFileToolClass *klass)
+{
+	klass->update_sensitivity = gth_file_tool_enhance_update_sensitivity;
+	klass->activate = gth_file_tool_enhance_activate;
+}
+
+
+GType
+gth_file_tool_enhance_get_type (void) {
+	static GType type_id = 0;
+	if (type_id == 0) {
+		static const GTypeInfo g_define_type_info = {
+			sizeof (GthFileToolEnhanceClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) gth_file_tool_enhance_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL,
+			sizeof (GthFileToolEnhance),
+			0,
+			(GInstanceInitFunc) gth_file_tool_enhance_instance_init,
+			NULL
+		};
+		type_id = g_type_register_static (GTH_TYPE_FILE_TOOL, "GthFileToolEnhance", &g_define_type_info, 0);
+	}
+	return type_id;
+}
diff --git a/extensions/file_tools/gth-file-tool-enhance.h b/extensions/file_tools/gth-file-tool-enhance.h
new file mode 100644
index 0000000..179af37
--- /dev/null
+++ b/extensions/file_tools/gth-file-tool-enhance.h
@@ -0,0 +1,52 @@
+/* -*- 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_ENHANCE_H
+#define GTH_FILE_TOOL_ENHANCE_H
+
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_FILE_TOOL_ENHANCE (gth_file_tool_enhance_get_type ())
+#define GTH_FILE_TOOL_ENHANCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_FILE_TOOL_ENHANCE, GthFileToolEnhance))
+#define GTH_FILE_TOOL_ENHANCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_FILE_TOOL_ENHANCE, GthFileToolEnhanceClass))
+#define GTH_IS_FILE_TOOL_ENHANCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_FILE_TOOL_ENHANCE))
+#define GTH_IS_FILE_TOOL_ENHANCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_FILE_TOOL_ENHANCE))
+#define GTH_FILE_TOOL_ENHANCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTH_TYPE_FILE_TOOL_ENHANCE, GthFileToolEnhanceClass))
+
+typedef struct _GthFileToolEnhance GthFileToolEnhance;
+typedef struct _GthFileToolEnhanceClass GthFileToolEnhanceClass;
+
+struct _GthFileToolEnhance {
+	GthFileTool parent_instance;
+};
+
+struct _GthFileToolEnhanceClass {
+	GthFileToolClass parent_class;
+};
+
+GType  gth_file_tool_enhance_get_type  (void);
+
+G_END_DECLS
+
+#endif /* GTH_FILE_TOOL_ENHANCE_H */
diff --git a/extensions/file_tools/main.c b/extensions/file_tools/main.c
index 54978f8..65819f6 100644
--- a/extensions/file_tools/main.c
+++ b/extensions/file_tools/main.c
@@ -26,6 +26,7 @@
 #include <gthumb.h>
 #include "gth-file-tool-crop.h"
 #include "gth-file-tool-desaturate.h"
+#include "gth-file-tool-enhance.h"
 #include "gth-file-tool-redo.h"
 #include "gth-file-tool-save.h"
 #include "gth-file-tool-undo.h"
@@ -39,6 +40,7 @@ gthumb_extension_activate (void)
 	gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_SAVE);
 	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_ENHANCE);
 }
 
 
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index aaf2e4d..6850226 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -53,6 +53,7 @@ PUBLIC_HEADER_FILES = 					\
 	gth-filter-editor-dialog.h			\
 	gth-filter-file.h				\
 	gth-folder-tree.h				\
+	gth-histogram.h					\
 	gth-hook.h					\
 	gth-icon-cache.h				\
 	gth-icon-view.h					\
@@ -158,6 +159,7 @@ gthumb_SOURCES = 					\
 	gth-filter-editor-dialog.c			\
 	gth-filter-file.c				\
 	gth-folder-tree.c				\
+	gth-histogram.c					\
 	gth-hook.c					\
 	gth-icon-cache.c				\
 	gth-icon-view.c					\
diff --git a/gthumb/gth-histogram.c b/gthumb/gth-histogram.c
new file mode 100644
index 0000000..7617426
--- /dev/null
+++ b/gthumb/gth-histogram.c
@@ -0,0 +1,218 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2001 The 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 <string.h>
+#include "gth-histogram.h"
+
+
+#define MAX_N_CHANNELS 4
+
+
+GthHistogram *
+gth_histogram_new (void)
+{
+	GthHistogram *histogram;
+	int              i;
+
+	histogram = g_new0 (GthHistogram, 1);
+
+	histogram->values = g_new0 (int *, MAX_N_CHANNELS + 1);
+	for (i = 0; i < MAX_N_CHANNELS + 1; i++)
+		histogram->values[i] = g_new0 (int, 256);
+
+	histogram->values_max = g_new0 (int, MAX_N_CHANNELS + 1);
+
+	return histogram;
+}
+
+
+void
+gth_histogram_free (GthHistogram *histogram)
+{
+	int i;
+
+	if (histogram == NULL)
+		return;
+
+	for (i = 0; i < MAX_N_CHANNELS + 1; i++)
+		g_free (histogram->values[i]);
+	g_free (histogram->values);
+	g_free (histogram->values_max);
+
+	g_free (histogram);
+}
+
+
+static void
+histogram_reset_values (GthHistogram *histogram)
+{
+	int i;
+
+	for (i = 0; i < MAX_N_CHANNELS + 1; i++) {
+		memset (histogram->values[i], 0, sizeof (int) * 256);
+		histogram->values_max[i] = 0;
+	}
+}
+
+
+void
+gth_histogram_calculate (GthHistogram    *histogram,
+			 const GdkPixbuf *pixbuf)
+{
+	int    **values = histogram->values;
+	int     *values_max = histogram->values_max;  
+	int      width, height, has_alpha, n_channels;
+	int      rowstride;
+	guchar  *line, *pixel;
+	int      i, j, max;
+
+	g_return_if_fail (histogram != NULL);
+
+	if (pixbuf == NULL) {
+		histogram->n_channels = 0;
+		histogram_reset_values (histogram);
+		return;
+	}
+
+	has_alpha  = gdk_pixbuf_get_has_alpha (pixbuf);
+	n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+	rowstride  = gdk_pixbuf_get_rowstride (pixbuf);
+	line       = gdk_pixbuf_get_pixels (pixbuf);
+	width      = gdk_pixbuf_get_width (pixbuf);
+	height     = gdk_pixbuf_get_height (pixbuf);
+
+	histogram->n_channels = n_channels + 1;
+	histogram_reset_values (histogram);
+
+	for (i = 0; i < height; i++) {
+		pixel = line;
+		line += rowstride;
+
+		for (j = 0; j < width; j++) {
+			/* count values for each RGB channel */		
+			values[1][pixel[0]] += 1;
+			values[2][pixel[1]] += 1;
+			values[3][pixel[2]] += 1;
+			if (n_channels > 3)
+				values[4][ pixel[3] ] += 1;
+				
+			/* count value for Value channel */
+			max = MAX (pixel[0], pixel[1]);
+			max = MAX (pixel[2], max);
+			values[0][max] += 1;
+
+			/* track max value for each channel */
+			values_max[0] = MAX (values_max[0], values[0][max]);
+			values_max[1] = MAX (values_max[1], values[1][pixel[0]]);
+			values_max[2] = MAX (values_max[2], values[2][pixel[1]]);
+			values_max[3] = MAX (values_max[3], values[3][pixel[2]]);
+			if (n_channels > 3)
+				values_max[4] = MAX (values_max[4], values[4][pixel[3]]);
+
+			pixel += n_channels;
+		}
+	}
+}
+
+
+double
+gth_histogram_get_count (GthHistogram *histogram,
+			 int              start,
+			 int              end)
+{
+	int    i;
+	double count = 0;
+
+	g_return_val_if_fail (histogram != NULL, 0.0);
+
+	for (i = start; i <= end; i++)
+		count += histogram->values[0][i];
+	
+	return count;
+}
+
+
+double
+gth_histogram_get_value (GthHistogram *histogram,
+			 int           channel,
+			 int           bin)
+{
+	g_return_val_if_fail (histogram != NULL, 0.0);
+
+	if ((channel < histogram->n_channels) && (bin >= 0) && (bin < 256))
+		return (double) histogram->values[channel][bin];
+
+	return 0.0;
+}
+
+
+double
+gth_histogram_get_channel (GthHistogram *histogram,
+			   int           channel,
+			   int           bin)
+{
+	g_return_val_if_fail (histogram != NULL, 0.0);
+
+	if (histogram->n_channels > 3)
+		return gth_histogram_get_value (histogram, channel + 1, bin);
+	else
+		return gth_histogram_get_value (histogram, channel, bin);
+}
+
+
+double
+gth_histogram_get_max (GthHistogram *histogram,
+		       int           channel)
+{
+	g_return_val_if_fail (histogram != NULL, 0.0);
+
+	if (channel < histogram->n_channels)
+		return (double) histogram->values_max[channel];
+
+	return 0.0;
+}
+
+
+int
+gth_histogram_get_nchannels (GthHistogram *histogram)
+{
+	g_return_val_if_fail (histogram != NULL, 0.0);
+	return histogram->n_channels - 1;
+}
+
+
+void
+gth_histogram_set_current_channel (GthHistogram *histogram,
+				   int           channel)
+{
+	g_return_if_fail (histogram != NULL);
+	histogram->cur_channel = channel;
+}
+
+
+int
+gth_histogram_get_current_channel (GthHistogram *histogram)
+{
+	g_return_val_if_fail (histogram != NULL, 0.0);
+	return histogram->cur_channel;
+}
diff --git a/gthumb/gth-histogram.h b/gthumb/gth-histogram.h
new file mode 100644
index 0000000..bb76978
--- /dev/null
+++ b/gthumb/gth-histogram.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2001-2009 The 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_HISTOGRAM_H
+#define GTH_HISTOGRAM_H
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#define MAX_N_CHANNELS 4
+
+typedef struct {
+	int   **values;
+	int    *values_max;
+	int     n_channels;
+	int     cur_channel;
+} GthHistogram;
+
+GthHistogram * gth_histogram_new                 (void);
+void           gth_histogram_free                (GthHistogram    *histogram);
+void           gth_histogram_calculate           (GthHistogram    *histogram,
+						  const GdkPixbuf *pixbuf);
+double         gth_histogram_get_count           (GthHistogram    *histogram,
+						  int              start,
+						  int              end);
+double         gth_histogram_get_value           (GthHistogram    *histogram,
+						  int              channel,
+						  int              bin);
+double         gth_histogram_get_channel         (GthHistogram    *histogram,
+						  int              channel,
+						  int              bin);
+double         gth_histogram_get_max             (GthHistogram    *histogram,
+						  int              channel);
+int            gth_histogram_get_nchannels       (GthHistogram    *histogram);
+void           gth_histogram_set_current_channel (GthHistogram    *histogram,
+						  int              channel);
+int            gth_histogram_get_current_channel (GthHistogram    *histogram);
+
+#endif /* GTH_HISTOGRAM_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]