Commit 7fa1a1c7 authored by Jesper Pedersen's avatar Jesper Pedersen Committed by Daniel P. Berrange

Add support for linear histogram

Add a config option to allow switching between liner and
logarithmic histrogram rendering
Signed-off-by: default avatarDaniel P. Berrange <dan@berrange.com>
parent cbe8b1f6
......@@ -51,6 +51,7 @@ G_DEFINE_TYPE(EntanglePreferences, entangle_preferences, G_TYPE_OBJECT);
#define SETTING_INTERFACE_AUTO_CONNECT "auto-connect"
#define SETTING_INTERFACE_SCREEN_BLANK "screen-blank"
#define SETTING_INTERFACE_PLUGINS "plugins"
#define SETTING_INTERFACE_HISTOGRAM_LINEAR "histogram-linear"
#define SETTING_CAPTURE_FILENAME_PATTERN "filename-pattern"
#define SETTING_CAPTURE_LAST_SESSION "last-session"
......@@ -72,8 +73,10 @@ G_DEFINE_TYPE(EntanglePreferences, entangle_preferences, G_TYPE_OBJECT);
#define SETTING_IMG_ONION_SKIN "onion-skin"
#define SETTING_IMG_ONION_LAYERS "onion-layers"
#define PROP_NAME_INTERFACE_AUTO_CONNECT SETTING_INTERFACE "-" SETTING_INTERFACE_AUTO_CONNECT
#define PROP_NAME_INTERFACE_SCREEN_BLANK SETTING_INTERFACE "-" SETTING_INTERFACE_SCREEN_BLANK
#define PROP_NAME_INTERFACE_HISTOGRAM_LINEAR SETTING_INTERFACE "-" SETTING_INTERFACE_HISTOGRAM_LINEAR
#define PROP_NAME_CAPTURE_FILENAME_PATTERN SETTING_CAPTURE "-" SETTING_CAPTURE_FILENAME_PATTERN
#define PROP_NAME_CAPTURE_LAST_SESSION SETTING_CAPTURE "-" SETTING_CAPTURE_LAST_SESSION
......@@ -100,6 +103,7 @@ enum {
PROP_INTERFACE_AUTO_CONNECT,
PROP_INTERFACE_SCREEN_BLANK,
PROP_INTERFACE_HISTOGRAM_LINEAR,
PROP_CAPTURE_FILENAME_PATTERN,
PROP_CAPTURE_LAST_SESSION,
......@@ -172,6 +176,12 @@ static void entangle_preferences_get_property(GObject *object,
SETTING_INTERFACE_SCREEN_BLANK));
break;
case PROP_INTERFACE_HISTOGRAM_LINEAR:
g_value_set_boolean(value,
g_settings_get_boolean(priv->interfaceSettings,
SETTING_INTERFACE_HISTOGRAM_LINEAR));
break;
case PROP_CAPTURE_LAST_SESSION:
dir = g_settings_get_string(priv->captureSettings,
SETTING_CAPTURE_LAST_SESSION);
......@@ -316,6 +326,12 @@ static void entangle_preferences_set_property(GObject *object,
g_value_get_boolean(value));
break;
case PROP_INTERFACE_HISTOGRAM_LINEAR:
g_settings_set_boolean(priv->interfaceSettings,
SETTING_INTERFACE_HISTOGRAM_LINEAR,
g_value_get_boolean(value));
break;
case PROP_CAPTURE_LAST_SESSION:
g_settings_set_string(priv->captureSettings,
SETTING_CAPTURE_LAST_SESSION,
......@@ -483,6 +499,17 @@ static void entangle_preferences_class_init(EntanglePreferencesClass *klass)
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
g_object_class_install_property(object_class,
PROP_INTERFACE_HISTOGRAM_LINEAR,
g_param_spec_boolean(PROP_NAME_INTERFACE_HISTOGRAM_LINEAR,
"Linear histogram",
"Use linear histogram",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
g_object_class_install_property(object_class,
PROP_CAPTURE_LAST_SESSION,
g_param_spec_string(PROP_NAME_CAPTURE_LAST_SESSION,
......@@ -771,6 +798,29 @@ void entangle_preferences_interface_set_screen_blank(EntanglePreferences *prefs,
}
gboolean entangle_preferences_interface_get_histogram_linear(EntanglePreferences *prefs)
{
g_return_val_if_fail(ENTANGLE_IS_PREFERENCES(prefs), FALSE);
EntanglePreferencesPrivate *priv = prefs->priv;
return g_settings_get_boolean(priv->interfaceSettings,
SETTING_INTERFACE_HISTOGRAM_LINEAR);
}
void entangle_preferences_interface_set_histogram_linear(EntanglePreferences *prefs, gboolean enabled)
{
g_return_if_fail(ENTANGLE_IS_PREFERENCES(prefs));
EntanglePreferencesPrivate *priv = prefs->priv;
g_settings_set_boolean(priv->interfaceSettings,
SETTING_INTERFACE_HISTOGRAM_LINEAR, enabled);
g_object_notify(G_OBJECT(prefs), PROP_NAME_INTERFACE_HISTOGRAM_LINEAR);
}
gchar **entangle_preferences_interface_get_plugins(EntanglePreferences *prefs)
{
g_return_val_if_fail(ENTANGLE_IS_PREFERENCES(prefs), NULL);
......
......@@ -64,6 +64,8 @@ void entangle_preferences_interface_set_screen_blank(EntanglePreferences *prefs,
gchar **entangle_preferences_interface_get_plugins(EntanglePreferences *prefs);
void entangle_preferences_interface_add_plugin(EntanglePreferences *prefs, const char *name);
void entangle_preferences_interface_remove_plugin(EntanglePreferences *prefs, const char *name);
gboolean entangle_preferences_interface_get_histogram_linear(EntanglePreferences *prefs);
void entangle_preferences_interface_set_histogram_linear(EntanglePreferences *prefs, gboolean enabled);
char *entangle_preferences_capture_get_last_session(EntanglePreferences *prefs);
void entangle_preferences_capture_set_last_session(EntanglePreferences *prefs, const gchar *dir);
......
......@@ -344,6 +344,18 @@ static void entangle_camera_manager_update_mask_enabled(EntangleCameraManager *m
}
static void entangle_camera_manager_update_histogram_linear(EntangleCameraManager *manager)
{
g_return_if_fail(ENTANGLE_IS_CAMERA_MANAGER(manager));
EntangleCameraManagerPrivate *priv = manager->priv;
EntanglePreferences *prefs = entangle_application_get_preferences(priv->application);
gboolean histogram_linear = entangle_preferences_interface_get_histogram_linear(prefs);
entangle_image_histogram_set_histogram_linear(priv->imageHistogram, histogram_linear);
}
static void do_presentation_monitor_toggled(GtkCheckMenuItem *menu, gpointer data)
{
g_return_if_fail(ENTANGLE_IS_CAMERA_MANAGER(data));
......@@ -440,7 +452,9 @@ static void entangle_camera_manager_prefs_changed(GObject *object G_GNUC_UNUSED,
EntangleCameraManager *manager = ENTANGLE_CAMERA_MANAGER(data);
if (g_str_equal(spec->name, "cms-enabled") ||
if (g_str_equal(spec->name, "interface-histogram-linear")) {
entangle_camera_manager_update_histogram_linear(manager);
} else if (g_str_equal(spec->name, "cms-enabled") ||
g_str_equal(spec->name, "cms-rgb-profile") ||
g_str_equal(spec->name, "cms-monitor-profile") ||
g_str_equal(spec->name, "cms-detect-system-profile") ||
......@@ -1541,6 +1555,7 @@ static void entangle_camera_manager_set_property(GObject *object,
directory = entangle_preferences_capture_get_last_session(prefs);
pattern = entangle_preferences_capture_get_filename_pattern(prefs);
entangle_camera_manager_update_histogram_linear(manager);
entangle_camera_manager_update_colour_transform(manager);
entangle_camera_manager_update_aspect_ratio(manager);
entangle_camera_manager_update_mask_opacity(manager);
......@@ -2154,6 +2169,12 @@ gboolean do_manager_key_release(GtkWidget *widget G_GNUC_UNUSED,
entangle_preferences_img_set_mask_enabled(prefs, !enabled);
} break;
case GDK_KEY_h: {
EntanglePreferences *prefs = entangle_application_get_preferences(priv->application);
gboolean linear = entangle_preferences_interface_get_histogram_linear(prefs);
entangle_preferences_interface_set_histogram_linear(prefs, !linear);
} break;
case GDK_KEY_a: {
if (priv->taskPreview) {
entangle_camera_autofocus_async(priv->camera,
......
......@@ -35,6 +35,7 @@ struct _EntangleImageHistogramPrivate {
double freq_green[255];
double freq_blue[255];
gboolean hasFreq;
gboolean linear;
gulong imageNotifyID;
EntangleImage *image;
};
......@@ -58,6 +59,7 @@ static void do_entangle_pixmap_setup(EntangleImageHistogram *histogram)
if (priv->image)
pixbuf = entangle_image_get_pixbuf(priv->image);
memset(priv->freq_red, 0, sizeof(priv->freq_red));
memset(priv->freq_green, 0, sizeof(priv->freq_green));
memset(priv->freq_blue, 0, sizeof(priv->freq_blue));
......@@ -73,7 +75,6 @@ static void do_entangle_pixmap_setup(EntangleImageHistogram *histogram)
guint stride = gdk_pixbuf_get_rowstride(pixbuf);
int x, y;
for (y = 0 ; y < h ; y++) {
guchar *pixel = pixels;
for (x = 0 ; x < w ; x++) {
......@@ -91,12 +92,6 @@ static void do_entangle_pixmap_setup(EntangleImageHistogram *histogram)
pixels += stride;
}
for (x = 0 ; x < 255 ; x++) {
priv->freq_red[x] = DOUBLE_EQUAL(priv->freq_red[x], 0.0) ? 0.0 : log(priv->freq_red[x]);
priv->freq_green[x] = DOUBLE_EQUAL(priv->freq_green[x], 0.0) ? 0.0 : log(priv->freq_green[x]);
priv->freq_blue[x] = DOUBLE_EQUAL(priv->freq_blue[x], 0.0) ? 0.0 : log(priv->freq_blue[x]);
}
priv->hasFreq = TRUE;
}
......@@ -173,6 +168,17 @@ static void entangle_image_histogram_draw_grid(cairo_t *cr, const float width, c
}
}
static double entangle_image_histogram_calculate_value(double d, gboolean l)
{
if (!l) {
return DOUBLE_EQUAL(d, 0.0) ? 0.0 : log(d);
}
return d;
}
static gboolean entangle_image_histogram_draw(GtkWidget *widget, cairo_t *cr)
{
g_return_val_if_fail(ENTANGLE_IS_IMAGE_HISTOGRAM(widget), FALSE);
......@@ -202,12 +208,16 @@ static gboolean entangle_image_histogram_draw(GtkWidget *widget, cairo_t *cr)
if (priv->hasFreq) {
for (idx = 0 ; idx < 255 ; idx++) {
if (priv->freq_red[idx] > peak)
peak = priv->freq_red[idx];
if (priv->freq_green[idx] > peak)
peak = priv->freq_green[idx];
if (priv->freq_blue[idx] > peak)
peak = priv->freq_blue[idx];
double rv = entangle_image_histogram_calculate_value(priv->freq_red[idx], priv->linear);
double gv = entangle_image_histogram_calculate_value(priv->freq_green[idx], priv->linear);
double bv = entangle_image_histogram_calculate_value(priv->freq_blue[idx], priv->linear);
if (rv > peak)
peak = rv;
if (gv > peak)
peak = gv;
if (bv > peak)
peak = bv;
}
cairo_set_line_width(cr, 3);
cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
......@@ -220,8 +230,9 @@ static gboolean entangle_image_histogram_draw(GtkWidget *widget, cairo_t *cr)
cairo_move_to(cr, 0, wh);
for (idx = 0 ; idx < 255 ; idx++) {
double rv = entangle_image_histogram_calculate_value(priv->freq_red[idx], priv->linear);
double x = (double)ww * (double)idx / 255.0;
double y = (double)(wh - 2) * (double)priv->freq_red[idx] / peak;
double y = (double)(wh - 2) * (double)rv / peak;
cairo_line_to(cr, x, wh - y);
}
......@@ -236,8 +247,9 @@ static gboolean entangle_image_histogram_draw(GtkWidget *widget, cairo_t *cr)
cairo_move_to(cr, 0, wh);
for (idx = 0 ; idx < 255 ; idx++) {
double gv = entangle_image_histogram_calculate_value(priv->freq_green[idx], priv->linear);
double x = (double)ww * (double)idx / 255.0;
double y = (double)(wh - 2) * (double)priv->freq_green[idx] / peak;
double y = (double)(wh - 2) * (double)gv / peak;
cairo_line_to(cr, x, wh - y);
}
......@@ -252,8 +264,9 @@ static gboolean entangle_image_histogram_draw(GtkWidget *widget, cairo_t *cr)
cairo_move_to(cr, 0, wh);
for (idx = 0 ; idx < 255 ; idx++) {
double bv = entangle_image_histogram_calculate_value(priv->freq_blue[idx], priv->linear);
double x = (double)ww * (double)idx / 255.0;
double y = (double)(wh - 2) * (double)priv->freq_blue[idx] / peak;
double y = (double)(wh - 2) * (double)bv / peak;
cairo_line_to(cr, x, wh - y);
}
......@@ -386,6 +399,28 @@ EntangleImage *entangle_image_histogram_get_image(EntangleImageHistogram *histog
return priv->image;
}
void entangle_image_histogram_set_histogram_linear(EntangleImageHistogram *histogram, gboolean linear)
{
g_return_if_fail(ENTANGLE_IS_IMAGE_HISTOGRAM(histogram));
EntangleImageHistogramPrivate *priv = histogram->priv;
priv->linear = linear;
gtk_widget_queue_draw(GTK_WIDGET(histogram));
}
gboolean entangle_image_histogram_get_histogram_linear(EntangleImageHistogram *histogram)
{
g_return_val_if_fail(ENTANGLE_IS_IMAGE_HISTOGRAM(histogram), FALSE);
EntangleImageHistogramPrivate *priv = histogram->priv;
return priv->linear;
}
/*
* Local variables:
* c-indent-level: 4
......
......@@ -60,6 +60,10 @@ void entangle_image_histogram_set_image(EntangleImageHistogram *histogram,
EntangleImage *image);
EntangleImage *entangle_image_histogram_get_image(EntangleImageHistogram *histogram);
void entangle_image_histogram_set_histogram_linear(EntangleImageHistogram *histogram,
gboolean linear);
gboolean entangle_image_histogram_get_histogram_linear(EntangleImageHistogram *histogram);
G_END_DECLS
#endif /* __ENTANGLE_IMAGE_HISTOGRAM_H__ */
......
......@@ -69,6 +69,7 @@ void do_cms_rendering_intent_changed(GtkComboBox *src, EntanglePreferencesDispla
void do_interface_auto_connect_toggled(GtkToggleButton *src, EntanglePreferencesDisplay *display);
void do_interface_screen_blank_toggled(GtkToggleButton *src, EntanglePreferencesDisplay *display);
void do_interface_histogram_linear_toggled(GtkToggleButton *src, EntanglePreferencesDisplay *display);
void do_capture_filename_pattern_changed(GtkEntry *src, EntanglePreferencesDisplay *display);
void do_capture_continuous_preview_toggled(GtkToggleButton *src, EntanglePreferencesDisplay *display);
......@@ -192,6 +193,15 @@ static void entangle_preferences_display_notify(GObject *object,
g_object_get(object, spec->name, &newvalue, NULL);
oldvalue = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tmp));
if (newvalue != oldvalue)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmp), newvalue);
} else if (strcmp(spec->name, "interface-histogram-linear") == 0) {
gboolean newvalue;
gboolean oldvalue;
g_object_get(object, spec->name, &newvalue, NULL);
oldvalue = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tmp));
if (newvalue != oldvalue)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmp), newvalue);
} else if (strcmp(spec->name, "capture-filename-pattern") == 0) {
......@@ -402,6 +412,9 @@ static void entangle_preferences_display_refresh(EntanglePreferencesDisplay *pre
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmp), entangle_preferences_interface_get_auto_connect(prefs));
tmp = GTK_WIDGET(gtk_builder_get_object(priv->builder, "interface-screen-blank"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmp), entangle_preferences_interface_get_screen_blank(prefs));
tmp = GTK_WIDGET(gtk_builder_get_object(priv->builder, "interface-histogram-linear"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmp),
entangle_preferences_interface_get_histogram_linear(prefs));
tmp = GTK_WIDGET(gtk_builder_get_object(priv->builder, "capture-filename-pattern"));
gtk_entry_set_text(GTK_ENTRY(tmp), entangle_preferences_capture_get_filename_pattern(prefs));
......@@ -688,6 +701,18 @@ void do_interface_screen_blank_toggled(GtkToggleButton *src, EntanglePreferences
}
void do_interface_histogram_linear_toggled(GtkToggleButton *src, EntanglePreferencesDisplay *preferences)
{
g_return_if_fail(ENTANGLE_IS_PREFERENCES_DISPLAY(preferences));
EntanglePreferencesDisplayPrivate *priv = preferences->priv;
EntanglePreferences *prefs = entangle_application_get_preferences(priv->application);
gboolean enabled = gtk_toggle_button_get_active(src);
entangle_preferences_interface_set_histogram_linear(prefs, enabled);
}
void do_capture_delete_file_toggled(GtkToggleButton *src, EntanglePreferencesDisplay *preferences)
{
g_return_if_fail(ENTANGLE_IS_PREFERENCES_DISPLAY(preferences));
......
......@@ -636,6 +636,22 @@
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="interface-histogram-linear">
<property name="label" translatable="yes">Show linear histogram</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="do_interface_histogram_linear_toggled" swapped="no"/>
</object>
<packing>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
......
......@@ -37,6 +37,12 @@
<description>Blank screen while capturing images</description>
</key>
<key type="b" name="histogram-linear">
<default>false</default>
<summary>Show linear histogram</summary>
<description>Show linear histogram instead of logarithmic</description>
</key>
<key type="as" name="plugins">
<default>[]</default>
<summary>Plugins</summary>
......@@ -150,6 +156,5 @@
<summary>Onion skin</summary>
<description>Enable image overlay display</description>
</key>
</schema>
</schemalist>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment