summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorMatthias Vogelgesang <matthias.vogelgesang@kit.edu>2013-07-18 12:44:18 +0200
committerMatthias Vogelgesang <matthias.vogelgesang@kit.edu>2013-07-18 12:44:18 +0200
commit9fdc54d27a8290b98d6fb7122af6beb5ab3b05db (patch)
tree5b015ba494ea74d8012488dd0a1cdaa83f071618 /bin
parentcd6b4ae0deb045751ce10f2845e9c0456cf21d3d (diff)
downloadlibuca-9fdc54d27a8290b98d6fb7122af6beb5ab3b05db.tar.gz
libuca-9fdc54d27a8290b98d6fb7122af6beb5ab3b05db.tar.bz2
libuca-9fdc54d27a8290b98d6fb7122af6beb5ab3b05db.tar.xz
libuca-9fdc54d27a8290b98d6fb7122af6beb5ab3b05db.zip
Fix histogram problems
Diffstat (limited to 'bin')
-rw-r--r--bin/gui/control.c17
-rw-r--r--bin/gui/egg-histogram-view.c197
-rw-r--r--bin/gui/egg-histogram-view.h10
3 files changed, 112 insertions, 112 deletions
diff --git a/bin/gui/control.c b/bin/gui/control.c
index 63101e8..3d108df 100644
--- a/bin/gui/control.c
+++ b/bin/gui/control.c
@@ -80,7 +80,7 @@ down_scale (ThreadData *data, gpointer buffer)
gint stride;
gint i = 0;
- egg_histogram_get_visible_range (EGG_HISTOGRAM_VIEW (data->histogram_view), &min, &max);
+ egg_histogram_get_range (EGG_HISTOGRAM_VIEW (data->histogram_view), &min, &max);
factor = 255.0 / (max - min);
output = data->pixels;
stride = (gint) 1 / data->zoom_factor;
@@ -129,7 +129,7 @@ up_scale (ThreadData *data, gpointer buffer)
gint i = 0;
gint zoom;
- egg_histogram_get_visible_range (EGG_HISTOGRAM_VIEW (data->histogram_view), &min, &max);
+ egg_histogram_get_range (EGG_HISTOGRAM_VIEW (data->histogram_view), &min, &max);
factor = 255.0 / (max - min);
output = data->pixels;
zoom = (gint) data->zoom_factor;
@@ -166,7 +166,6 @@ up_scale (ThreadData *data, gpointer buffer)
}
}
-
static void
convert_grayscale_to_rgb (ThreadData *data, gpointer buffer)
{
@@ -238,6 +237,7 @@ preview_frames (void *args)
uca_camera_grab (data->camera, buffer, &error);
if (error == NULL) {
+ egg_histogram_view_update (EGG_HISTOGRAM_VIEW (data->histogram_view), buffer);
convert_grayscale_to_rgb (data, buffer);
gdk_threads_enter ();
@@ -589,7 +589,7 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)
g_signal_connect (camera, "notify::roi-width", (GCallback) on_roi_width_changed, &td);
g_signal_connect (camera, "notify::roi-height", (GCallback) on_roi_height_changed, &td);
- histogram_view = egg_histogram_view_new ();
+ histogram_view = egg_histogram_view_new (width * height, bits_per_sample, 256);
property_tree_view = egg_property_tree_view_new (G_OBJECT (camera));
image = GTK_WIDGET (gtk_builder_get_object (builder, "image"));
histogram_box = GTK_BOX (gtk_builder_get_object (builder, "histogram-box"));
@@ -615,9 +615,8 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)
n_frames = mem_size * 1024 * 1024 / image_size;
ring_buffer = ring_buffer_new (image_size, n_frames);
- egg_histogram_view_set_data (EGG_HISTOGRAM_VIEW (histogram_view),
- ring_buffer_get_current_pointer (ring_buffer),
- width * height, bits_per_sample, 256);
+ egg_histogram_view_update (EGG_HISTOGRAM_VIEW (histogram_view),
+ ring_buffer_get_current_pointer (ring_buffer));
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
@@ -646,11 +645,11 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)
/* Hook up signals */
g_object_bind_property (gtk_builder_get_object (builder, "min-bin-value-adjustment"), "value",
td.histogram_view, "minimum-bin-value",
- G_BINDING_DEFAULT);
+ G_BINDING_BIDIRECTIONAL);
g_object_bind_property (max_bin_adjustment, "value",
td.histogram_view, "maximum-bin-value",
- G_BINDING_DEFAULT);
+ G_BINDING_BIDIRECTIONAL);
g_object_bind_property (gtk_builder_get_object (builder, "repeat-checkbutton"), "active",
gtk_builder_get_object (builder, "repeat-box"), "sensitive", 0);
diff --git a/bin/gui/egg-histogram-view.c b/bin/gui/egg-histogram-view.c
index 812af7a..912c2fa 100644
--- a/bin/gui/egg-histogram-view.c
+++ b/bin/gui/egg-histogram-view.c
@@ -34,15 +34,16 @@ struct _EggHistogramViewPrivate
/* This could be moved into a real histogram class */
guint n_bins;
gint *bins;
- gint *grabbed;
- gint min_border; /* threshold set in screen units */
- gint max_border;
+ /* gdouble *grabbed; */
+ enum {
+ GRAB_MIN,
+ GRAB_MAX
+ } grabbed;
+ gdouble max;
gdouble min_value; /* lowest value of the first bin */
gdouble max_value; /* highest value of the last bin */
- gdouble range;
- gpointer data;
gint n_elements;
gint n_bits;
};
@@ -67,104 +68,82 @@ static guint egg_histogram_view_signals[LAST_SIGNAL] = { 0 };
GtkWidget *
-egg_histogram_view_new (void)
+egg_histogram_view_new (guint n_elements,
+ guint n_bits,
+ guint n_bins)
{
EggHistogramView *view;
-
- view = EGG_HISTOGRAM_VIEW (g_object_new (EGG_TYPE_HISTOGRAM_VIEW, NULL));
- return GTK_WIDGET (view);
-}
-
-void
-egg_histogram_view_set_data (EggHistogramView *view,
- gpointer data,
- guint n_elements,
- guint n_bits,
- guint n_bins)
-{
EggHistogramViewPrivate *priv;
- g_return_if_fail (EGG_IS_HISTOGRAM_VIEW (view));
+ view = EGG_HISTOGRAM_VIEW (g_object_new (EGG_TYPE_HISTOGRAM_VIEW, NULL));
priv = view->priv;
- if (priv->bins != NULL)
- g_free (priv->bins);
-
- priv->data = data;
priv->bins = g_malloc0 (n_bins * sizeof (guint));
priv->n_bins = n_bins;
priv->n_bits = n_bits;
priv->n_elements = n_elements;
priv->min_value = 0.0;
- priv->max_value = (gint) pow(2, n_bits) - 1;
+ priv->max_value = priv->max = (gint) pow (2, n_bits) - 1;
- priv->min_border = 0;
- priv->max_border = 256;
- priv->range = priv->max_value - priv->min_value;
+ return GTK_WIDGET (view);
}
void
-egg_histogram_get_visible_range (EggHistogramView *view, gdouble *min, gdouble *max)
+egg_histogram_view_update (EggHistogramView *view,
+ gpointer buffer)
{
EggHistogramViewPrivate *priv;
- GtkAllocation allocation;
- gdouble width;
+ guint n_bins;
g_return_if_fail (EGG_IS_HISTOGRAM_VIEW (view));
-
- gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
- width = (gdouble) allocation.width - 2 * BORDER;
priv = view->priv;
-
- *min = (priv->min_border - 2) / width * priv->range;
- *max = (priv->max_border - 2) / width * priv->range;
-}
-
-static void
-set_max_border (EggHistogramView *view)
-{
- GtkAllocation allocation;
-
- g_return_if_fail (EGG_IS_HISTOGRAM_VIEW (view));
- gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
- view->priv->max_border = allocation.width - 2 * BORDER;
-}
-
-static void
-compute_histogram (EggHistogramViewPrivate *priv)
-{
- guint n_bins = priv->n_bins - 1;
+ n_bins = priv->n_bins - 1;
for (guint i = 0; i < priv->n_bins; i++)
priv->bins[i] = 0;
if (priv->n_bits == 8) {
- guint8 *data = (guint8 *) priv->data;
+ guint8 *data = (guint8 *) buffer;
for (guint i = 0; i < priv->n_elements; i++) {
guint8 v = data[i];
- if (v >= priv->min_value && v <= priv->max_value) {
- guint index = (guint) round (((gdouble) v) / priv->max_value * n_bins);
- priv->bins[index]++;
- }
+ guint index = (guint) round (((gdouble) v) / priv->max * n_bins);
+ priv->bins[index]++;
}
}
else {
- guint16 *data = (guint16 *) priv->data;
+ guint16 *data = (guint16 *) buffer;
for (guint i = 0; i < priv->n_elements; i++) {
guint16 v = data[i];
- if (v >= priv->min_value && v <= priv->max_value) {
- guint index = (guint) floor (((gdouble ) v) / priv->max_value * n_bins);
- priv->bins[index]++;
- }
+ guint index = (guint) floor (((gdouble ) v) / priv->max * n_bins);
+ priv->bins[index]++;
}
}
}
+void
+egg_histogram_get_range (EggHistogramView *view,
+ gdouble *min,
+ gdouble *max)
+{
+ EggHistogramViewPrivate *priv;
+ GtkAllocation allocation;
+ gdouble width;
+
+ g_return_if_fail (EGG_IS_HISTOGRAM_VIEW (view));
+
+ gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
+ width = (gdouble) allocation.width - 2 * BORDER;
+ priv = view->priv;
+
+ *min = priv->min_value;
+ *max = priv->max_value;
+}
+
static void
set_cursor_type (EggHistogramView *view, GdkCursorType cursor_type)
{
@@ -224,6 +203,7 @@ egg_histogram_view_expose (GtkWidget *widget,
GtkStyle *style;
cairo_t *cr;
gint width, height;
+ gdouble left, right;
priv = EGG_HISTOGRAM_VIEW_GET_PRIVATE (widget);
cr = gdk_cairo_create (gtk_widget_get_window (widget));
@@ -253,15 +233,16 @@ egg_histogram_view_expose (GtkWidget *widget,
if (priv->bins == NULL)
goto cleanup;
- compute_histogram (priv);
-
/* Draw border areas */
gdk_cairo_set_source_color (cr, &style->dark[GTK_STATE_NORMAL]);
- cairo_rectangle (cr, BORDER, BORDER, priv->min_border + 0.5, height - 1);
+ left = ((gint) (priv->min_value / priv->max * width)) + 0.5;
+ cairo_rectangle (cr, BORDER, BORDER, left, height - 1);
cairo_fill (cr);
- cairo_rectangle (cr, priv->max_border + 0.5, BORDER, width - priv->max_border + 0.5, height - 1);
+ right = ((gint) (priv->max_value / priv->max * width)) + 0.5;
+
+ cairo_rectangle (cr, right, BORDER, width - right, height - 1);
cairo_fill (cr);
/* Draw spikes */
@@ -313,8 +294,7 @@ egg_histogram_view_set_property (GObject *object,
v, priv->max_value);
else {
priv->min_value = v;
- priv->range = priv->max_value - v;
- priv->min_border = 0;
+ gtk_widget_queue_draw (GTK_WIDGET (object));
}
}
break;
@@ -328,8 +308,7 @@ egg_histogram_view_set_property (GObject *object,
v, priv->min_value);
else {
priv->max_value = v;
- priv->range = v - priv->min_value;
- set_max_border (EGG_HISTOGRAM_VIEW (object));
+ gtk_widget_queue_draw (GTK_WIDGET (object));
}
}
break;
@@ -366,28 +345,39 @@ egg_histogram_view_get_property (GObject *object,
}
}
+static gdouble
+screen_to_histogram_coordinate (EggHistogramViewPrivate *priv,
+ GtkAllocation *allocation,
+ gint x)
+{
+ return (((gdouble) x) / (allocation->width - BORDER)) * priv->max;
+}
+
static gboolean
is_on_border (EggHistogramViewPrivate *priv,
+ GtkAllocation *allocation,
gint x)
{
- gint d1 = (priv->min_border + BORDER) - x;
- gint d2 = (priv->max_border + BORDER) - x;
- return ABS (d1) < 6 || ABS (d2) < 6;
+ gdouble coord;
+
+ coord = screen_to_histogram_coordinate (priv, allocation , x);
+ return (ABS (coord - priv->min_value) < 6) || (ABS (coord - priv->max_value) < 6);
}
-static gint *
-get_grabbed_border (EggHistogramViewPrivate *priv,
- gint x)
+static void
+set_grab_value (EggHistogramView *view,
+ gdouble value)
{
- gint d1 = (priv->min_border + BORDER) - x;
- gint d2 = (priv->max_border + BORDER) - x;
-
- if (ABS (d1) < 6)
- return &priv->min_border;
- else if (ABS (d2) < 6)
- return &priv->max_border;
-
- return NULL;
+ if (view->priv->grabbed == GRAB_MIN) {
+ view->priv->min_value = value;
+ g_object_notify_by_pspec (G_OBJECT (view),
+ egg_histogram_view_properties[PROP_MINIMUM_BIN_VALUE]);
+ }
+ else {
+ view->priv->max_value = value;
+ g_object_notify_by_pspec (G_OBJECT (view),
+ egg_histogram_view_properties[PROP_MAXIMUM_BIN_VALUE]);
+ }
}
static gboolean
@@ -396,22 +386,24 @@ egg_histogram_view_motion_notify (GtkWidget *widget,
{
EggHistogramView *view;
EggHistogramViewPrivate *priv;
+ GtkAllocation allocation;
view = EGG_HISTOGRAM_VIEW (widget);
priv = view->priv;
+ gtk_widget_get_allocation (widget, &allocation);
if (priv->grabbing) {
- GtkAllocation allocation;
+ gdouble coord;
- gtk_widget_get_allocation (widget, &allocation);
+ coord = screen_to_histogram_coordinate (priv, &allocation, event->x);
- if ((event->x + BORDER > 0) && (event->x + BORDER < allocation.width)) {
- *priv->grabbed = event->x;
- gtk_widget_queue_draw (widget);
- }
+ if (ABS (priv->max_value - priv->min_value) > 8.0)
+ set_grab_value (view, coord);
+
+ gtk_widget_queue_draw (widget);
}
else {
- if (is_on_border (priv, event->x))
+ if (is_on_border (priv, &allocation, event->x))
set_cursor_type (view, GDK_FLEUR);
else
set_cursor_type (view, GDK_ARROW);
@@ -429,6 +421,7 @@ egg_histogram_view_button_release (GtkWidget *widget,
view = EGG_HISTOGRAM_VIEW (widget);
set_cursor_type (view, GDK_ARROW);
view->priv->grabbing = FALSE;
+
g_signal_emit (widget, egg_histogram_view_signals[CHANGED], 0);
return TRUE;
@@ -440,13 +433,24 @@ egg_histogram_view_button_press (GtkWidget *widget,
{
EggHistogramView *view;
EggHistogramViewPrivate *priv;
+ GtkAllocation allocation;
view = EGG_HISTOGRAM_VIEW (widget);
priv = view->priv;
+ gtk_widget_get_allocation (widget, &allocation);
+
+ if (is_on_border (priv, &allocation, event->x)) {
+ gdouble coord;
- if (is_on_border (priv, event->x)) {
priv->grabbing = TRUE;
- priv->grabbed = get_grabbed_border (priv, event->x);
+ coord = screen_to_histogram_coordinate (priv, &allocation, event->x);
+
+ if (ABS (coord - priv->min_value < 6))
+ priv->grabbed = GRAB_MIN;
+ else if (ABS (coord - priv->max_value < 6))
+ priv->grabbed = GRAB_MAX;
+
+ set_grab_value (view, coord);
set_cursor_type (view, GDK_FLEUR);
}
@@ -507,11 +511,10 @@ egg_histogram_view_init (EggHistogramView *view)
view->priv = priv = EGG_HISTOGRAM_VIEW_GET_PRIVATE (view);
priv->bins = NULL;
- priv->data = NULL;
priv->n_bins = 0;
priv->n_elements = 0;
- priv->min_value = priv->min_border = 0;
- priv->max_value = priv->max_border = 256;
+ priv->min_value = 0;
+ priv->max_value = 256;
priv->cursor_type = GDK_ARROW;
priv->grabbing = FALSE;
diff --git a/bin/gui/egg-histogram-view.h b/bin/gui/egg-histogram-view.h
index 7a62fca..afb0ad6 100644
--- a/bin/gui/egg-histogram-view.h
+++ b/bin/gui/egg-histogram-view.h
@@ -50,14 +50,12 @@ struct _EggHistogramViewClass
};
GType egg_histogram_view_get_type (void);
-GtkWidget * egg_histogram_view_new (void);
-void egg_histogram_view_set_data (EggHistogramView *view,
- gpointer data,
- guint n_elements,
+GtkWidget * egg_histogram_view_new (guint n_elements,
guint n_bits,
guint n_bins);
-void egg_histogram_get_visible_range
- (EggHistogramView *view,
+void egg_histogram_view_update (EggHistogramView *view,
+ gpointer data);
+void egg_histogram_get_range (EggHistogramView *view,
gdouble *min,
gdouble *max);