Commit fc9da4c9 authored by Michael Natterer's avatar Michael Natterer 😴

app: allow to toggle the histogram dialog between gamma and linear

Change GimpHistogram to take a "gboolean linear" parameter and always
honor that parameter, so both kinds of histograms can now be created
for all drawables.

Add a horrible "Linear" toggle to the histogram dockable which always
defaults to the active layer's actual pixel format, but can be
switched at any time. This UI is ugly and needs to change.

On the PDB, default to gamma-corrected if the plug-in is unaware of
higher precision, and to the drawable's native pixel format otherwise.

Other places using histograms (e.g. levels, curves) are unchanged.
parent d5bd26fd
......@@ -48,7 +48,7 @@ gimp_drawable_equalize (GimpDrawable *drawable,
image = gimp_item_get_image (GIMP_ITEM (drawable));
selection = gimp_image_get_mask (image);
hist = gimp_histogram_new (TRUE);
hist = gimp_histogram_new (FALSE);
gimp_drawable_calculate_histogram (drawable, hist);
equalize = gegl_node_new_child (NULL,
......
......@@ -53,7 +53,7 @@ gimp_drawable_levels_stretch (GimpDrawable *drawable,
config = g_object_new (GIMP_TYPE_LEVELS_CONFIG, NULL);
histogram = gimp_histogram_new (TRUE);
histogram = gimp_histogram_new (FALSE);
gimp_drawable_calculate_histogram (drawable, histogram);
gimp_levels_config_stretch (config, histogram,
......
......@@ -44,10 +44,10 @@ enum
struct _GimpHistogramPrivate
{
gboolean gamma_correct;
gint n_channels;
gint n_bins;
gdouble *values;
gboolean linear;
gint n_channels;
gint n_bins;
gdouble *values;
};
......@@ -188,11 +188,11 @@ gimp_histogram_get_memsize (GimpObject *object,
/* public functions */
GimpHistogram *
gimp_histogram_new (gboolean gamma_correct)
gimp_histogram_new (gboolean linear)
{
GimpHistogram *histogram = g_object_new (GIMP_TYPE_HISTOGRAM, NULL);
histogram->priv->gamma_correct = gamma_correct;
histogram->priv->linear = linear;
return histogram;
}
......@@ -213,7 +213,7 @@ gimp_histogram_duplicate (GimpHistogram *histogram)
g_return_val_if_fail (GIMP_IS_HISTOGRAM (histogram), NULL);
dup = gimp_histogram_new (histogram->priv->gamma_correct);
dup = gimp_histogram_new (histogram->priv->linear);
dup->priv->n_channels = histogram->priv->n_channels;
dup->priv->n_bins = histogram->priv->n_bins;
......@@ -254,57 +254,55 @@ gimp_histogram_calculate (GimpHistogram *histogram,
if (babl_format_is_palette (format))
{
if (babl_format_has_alpha (format))
format = babl_format ("R'G'B'A float");
{
if (priv->linear)
format = babl_format ("RGB float");
else
format = babl_format ("R'G'B' float");
}
else
format = babl_format ("R'G'B' float");
{
if (priv->linear)
format = babl_format ("RGBA float");
else
format = babl_format ("R'G'B'A float");
}
}
else
{
const Babl *model = babl_format_get_model (format);
if (model == babl_model ("Y"))
if (model == babl_model ("Y") ||
model == babl_model ("Y'"))
{
if (priv->gamma_correct)
format = babl_format ("Y' float");
else
if (priv->linear)
format = babl_format ("Y float");
}
else if (model == babl_model ("Y'"))
{
format = babl_format ("Y' float");
}
else if (model == babl_model ("YA"))
{
if (priv->gamma_correct)
format = babl_format ("Y'A float");
else
format = babl_format ("YA float");
}
else if (model == babl_model ("Y'A"))
{
format = babl_format ("Y'A float");
format = babl_format ("Y' float");
}
else if (model == babl_model ("RGB"))
else if (model == babl_model ("YA") ||
model == babl_model ("Y'A"))
{
if (priv->gamma_correct)
format = babl_format ("R'G'B' float");
if (priv->linear)
format = babl_format ("YA float");
else
format = babl_format ("RGB float");
}
else if (model == babl_model ("R'G'B'"))
{
format = babl_format ("R'G'B' float");
format = babl_format ("Y'A float");
}
else if (model == babl_model ("RGBA"))
else if (model == babl_model ("RGB") ||
model == babl_model ("R'G'B'"))
{
if (priv->gamma_correct)
format = babl_format ("R'G'B'A float");
if (priv->linear)
format = babl_format ("RGB float");
else
format = babl_format ("RGBA float");
format = babl_format ("R'G'B' float");
}
else if (model == babl_model ("R'G'B'A"))
else if (model == babl_model ("RGBA") ||
model == babl_model ("R'G'B'A"))
{
format = babl_format ("R'G'B'A float");
if (priv->linear)
format = babl_format ("RGBA float");
else
format = babl_format ("R'G'B'A float");
}
else
{
......
......@@ -50,7 +50,7 @@ struct _GimpHistogramClass
GType gimp_histogram_get_type (void) G_GNUC_CONST;
GimpHistogram * gimp_histogram_new (gboolean gamma_correct);
GimpHistogram * gimp_histogram_new (gboolean linear);
GimpHistogram * gimp_histogram_duplicate (GimpHistogram *histogram);
......
......@@ -630,11 +630,23 @@ histogram_invoker (GimpProcedure *procedure,
if (success)
{
GimpHistogram *histogram = gimp_histogram_new (TRUE);
gint start = start_range;
gint end = end_range;
GimpHistogram *histogram;
gint start = start_range;
gint end = end_range;
gboolean precision_enabled;
gboolean linear;
gint n_bins;
precision_enabled =
gimp->plug_in_manager->current_plug_in &&
gimp_plug_in_precision_enabled (gimp->plug_in_manager->current_plug_in);
if (precision_enabled)
linear = gimp_drawable_get_linear (drawable);
else
linear = FALSE;
histogram = gimp_histogram_new (linear);
gimp_drawable_calculate_histogram (drawable, histogram);
n_bins = gimp_histogram_n_bins (histogram);
......@@ -658,9 +670,7 @@ histogram_invoker (GimpProcedure *procedure,
g_object_unref (histogram);
if (n_bins == 256 ||
! gimp->plug_in_manager->current_plug_in ||
! gimp_plug_in_precision_enabled (gimp->plug_in_manager->current_plug_in))
if (n_bins == 256 || ! precision_enabled)
{
mean *= 255;
std_dev *= 255;
......
......@@ -401,11 +401,23 @@ drawable_histogram_invoker (GimpProcedure *procedure,
if (success)
{
GimpHistogram *histogram = gimp_histogram_new (TRUE);
GimpHistogram *histogram;
gint n_bins;
gint start;
gboolean precision_enabled;
gboolean linear;
gint end;
precision_enabled =
gimp->plug_in_manager->current_plug_in &&
gimp_plug_in_precision_enabled (gimp->plug_in_manager->current_plug_in);
if (precision_enabled)
linear = gimp_drawable_get_linear (drawable);
else
linear = FALSE;
histogram = gimp_histogram_new (linear);
gimp_drawable_calculate_histogram (drawable, histogram);
n_bins = gimp_histogram_n_bins (histogram);
......@@ -426,9 +438,7 @@ drawable_histogram_invoker (GimpProcedure *procedure,
g_object_unref (histogram);
if (n_bins == 256 ||
! gimp->plug_in_manager->current_plug_in ||
! gimp_plug_in_precision_enabled (gimp->plug_in_manager->current_plug_in))
if (n_bins == 256 || ! precision_enabled)
{
mean *= 255;
std_dev *= 255;
......
......@@ -225,7 +225,7 @@ gimp_curves_tool_initialize (GimpTool *tool,
gimp_int_combo_box_set_sensitivity (GIMP_INT_COMBO_BOX (c_tool->channel_menu),
curves_menu_sensitivity, drawable, NULL);
histogram = gimp_histogram_new (TRUE);
histogram = gimp_histogram_new (FALSE);
gimp_drawable_calculate_histogram (drawable, histogram);
gimp_histogram_view_set_background (GIMP_HISTOGRAM_VIEW (c_tool->graph),
histogram);
......
......@@ -169,7 +169,7 @@ gimp_levels_tool_class_init (GimpLevelsToolClass *klass)
static void
gimp_levels_tool_init (GimpLevelsTool *tool)
{
tool->histogram = gimp_histogram_new (TRUE);
tool->histogram = gimp_histogram_new (FALSE);
}
static void
......
......@@ -121,7 +121,7 @@ gimp_threshold_tool_class_init (GimpThresholdToolClass *klass)
static void
gimp_threshold_tool_init (GimpThresholdTool *t_tool)
{
t_tool->histogram = gimp_histogram_new (TRUE);
t_tool->histogram = gimp_histogram_new (FALSE);
}
static void
......
......@@ -41,8 +41,24 @@
#include "gimp-intl.h"
enum
{
PROP_0,
PROP_LINEAR
};
static void gimp_histogram_editor_docked_iface_init (GimpDockedInterface *iface);
static void gimp_histogram_editor_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_histogram_editor_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_histogram_editor_set_aux_info (GimpDocked *docked,
GList *aux_info);
static GList * gimp_histogram_editor_get_aux_info (GimpDocked *docked);
......@@ -53,6 +69,8 @@ static void gimp_histogram_editor_layer_changed (GimpImage *image,
GimpHistogramEditor *editor);
static void gimp_histogram_editor_frozen_update (GimpHistogramEditor *editor,
const GParamSpec *pspec);
static void gimp_histogram_editor_buffer_update (GimpHistogramEditor *editor,
const GParamSpec *pspec);
static void gimp_histogram_editor_update (GimpHistogramEditor *editor);
static gboolean gimp_histogram_editor_idle_update (GimpHistogramEditor *editor);
......@@ -78,9 +96,20 @@ static GimpDockedInterface *parent_docked_iface = NULL;
static void
gimp_histogram_editor_class_init (GimpHistogramEditorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpImageEditorClass *image_editor_class = GIMP_IMAGE_EDITOR_CLASS (klass);
object_class->set_property = gimp_histogram_editor_set_property;
object_class->get_property = gimp_histogram_editor_get_property;
image_editor_class->set_image = gimp_histogram_editor_set_image;
g_object_class_install_property (object_class, PROP_LINEAR,
g_param_spec_boolean ("linear",
_("Linear"), NULL,
TRUE,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
}
static void
......@@ -90,6 +119,7 @@ gimp_histogram_editor_init (GimpHistogramEditor *editor)
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *menu;
GtkWidget *button;
GtkWidget *table;
gint i;
......@@ -118,10 +148,6 @@ gimp_histogram_editor_init (GimpHistogramEditor *editor)
gtk_box_pack_start (GTK_BOX (editor), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
label = gtk_label_new (_("Channel:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
editor->menu = menu = gimp_prop_enum_combo_box_new (G_OBJECT (view),
"histogram-channel",
0, 0);
......@@ -135,12 +161,26 @@ gimp_histogram_editor_init (GimpHistogramEditor *editor)
gtk_box_pack_start (GTK_BOX (hbox), menu, FALSE, FALSE, 0);
gtk_widget_show (menu);
gimp_help_set_help_data (editor->menu,
_("Histogram channel"), NULL);
menu = gimp_prop_enum_icon_box_new (G_OBJECT (view),
"histogram-scale", "gimp-histogram",
0, 0);
gtk_box_pack_end (GTK_BOX (hbox), menu, FALSE, FALSE, 0);
gtk_widget_show (menu);
button = gimp_prop_check_button_new (G_OBJECT (editor), "linear", NULL);
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
gimp_help_set_help_data (button,
"This button switches between a histogram in "
"sRGB (gamma corrected) space and a histogram "
"in linear space. Also, it's horrible UI and "
"needs to be changed.", NULL);
gtk_box_pack_start (GTK_BOX (editor), editor->box, TRUE, TRUE, 0);
gtk_widget_show (GTK_WIDGET (editor->box));
......@@ -203,6 +243,65 @@ gimp_histogram_editor_docked_iface_init (GimpDockedInterface *docked_iface)
docked_iface->get_aux_info = gimp_histogram_editor_get_aux_info;
}
static void
gimp_histogram_editor_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpHistogramEditor *editor = GIMP_HISTOGRAM_EDITOR (object);
GimpHistogramView *view = GIMP_HISTOGRAM_BOX (editor->box)->view;
switch (property_id)
{
case PROP_LINEAR:
editor->linear = g_value_get_boolean (value);
if (editor->histogram)
{
g_object_unref (editor->histogram);
editor->histogram = NULL;
gimp_histogram_view_set_histogram (view, NULL);
}
if (editor->bg_histogram)
{
g_object_unref (editor->bg_histogram);
editor->bg_histogram = NULL;
gimp_histogram_view_set_background (view, NULL);
}
gimp_histogram_editor_update (editor);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_histogram_editor_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpHistogramEditor *editor = GIMP_HISTOGRAM_EDITOR (object);
switch (property_id)
{
case PROP_LINEAR:
g_value_set_boolean (value, editor->linear);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_histogram_editor_set_aux_info (GimpDocked *docked,
GList *aux_info)
......@@ -280,10 +379,6 @@ gimp_histogram_editor_set_image (GimpImageEditor *image_editor,
if (image)
{
editor->histogram = gimp_histogram_new (TRUE);
gimp_histogram_view_set_histogram (view, editor->histogram);
g_signal_connect_object (image, "mode-changed",
G_CALLBACK (gimp_histogram_editor_menu_update),
editor, G_CONNECT_SWAPPED);
......@@ -310,10 +405,18 @@ gimp_histogram_editor_layer_changed (GimpImage *image,
{
if (editor->drawable)
{
if (editor->bg_histogram)
GimpHistogramView *view = GIMP_HISTOGRAM_BOX (editor->box)->view;
if (editor->histogram)
{
GimpHistogramView *view = GIMP_HISTOGRAM_BOX (editor->box)->view;
g_object_unref (editor->histogram);
editor->histogram = NULL;
gimp_histogram_view_set_histogram (view, NULL);
}
if (editor->bg_histogram)
{
g_object_unref (editor->bg_histogram);
editor->bg_histogram = NULL;
......@@ -329,6 +432,9 @@ gimp_histogram_editor_layer_changed (GimpImage *image,
g_signal_handlers_disconnect_by_func (editor->drawable,
gimp_histogram_editor_update,
editor);
g_signal_handlers_disconnect_by_func (editor->drawable,
gimp_histogram_editor_buffer_update,
editor);
g_signal_handlers_disconnect_by_func (editor->drawable,
gimp_histogram_editor_frozen_update,
editor);
......@@ -345,6 +451,9 @@ gimp_histogram_editor_layer_changed (GimpImage *image,
g_signal_connect_object (editor->drawable, "notify::frozen",
G_CALLBACK (gimp_histogram_editor_frozen_update),
editor, G_CONNECT_SWAPPED);
g_signal_connect_object (editor->drawable, "notify::buffer",
G_CALLBACK (gimp_histogram_editor_buffer_update),
editor, G_CONNECT_SWAPPED);
g_signal_connect_object (editor->drawable, "update",
G_CALLBACK (gimp_histogram_editor_update),
editor, G_CONNECT_SWAPPED);
......@@ -355,7 +464,7 @@ gimp_histogram_editor_layer_changed (GimpImage *image,
G_CALLBACK (gimp_histogram_editor_name_update),
editor, G_CONNECT_SWAPPED);
gimp_histogram_editor_update (editor);
gimp_histogram_editor_buffer_update (editor, NULL);
}
else if (editor->histogram)
{
......@@ -370,16 +479,32 @@ gimp_histogram_editor_layer_changed (GimpImage *image,
static gboolean
gimp_histogram_editor_validate (GimpHistogramEditor *editor)
{
if (! editor->valid && editor->histogram)
if (! editor->valid)
{
if (editor->drawable)
gimp_drawable_calculate_histogram (editor->drawable, editor->histogram);
{
if (! editor->histogram)
{
GimpHistogramView *view = GIMP_HISTOGRAM_BOX (editor->box)->view;
editor->histogram = gimp_histogram_new (editor->linear);
gimp_histogram_view_set_histogram (view, editor->histogram);
}
gimp_drawable_calculate_histogram (editor->drawable,
editor->histogram);
}
else
gimp_histogram_clear_values (editor->histogram);
{
if (editor->histogram)
gimp_histogram_clear_values (editor->histogram);
}
gimp_histogram_editor_info_update (editor);
editor->valid = TRUE;
if (editor->histogram)
editor->valid = TRUE;
}
return editor->valid;
......@@ -417,6 +542,15 @@ gimp_histogram_editor_frozen_update (GimpHistogramEditor *editor,
}
}
static void
gimp_histogram_editor_buffer_update (GimpHistogramEditor *editor,
const GParamSpec *pspec)
{
g_object_set (editor,
"linear", gimp_drawable_get_linear (editor->drawable),
NULL);
}
static void
gimp_histogram_editor_update (GimpHistogramEditor *editor)
{
......
......@@ -36,6 +36,8 @@ struct _GimpHistogramEditor
{
GimpImageEditor parent_instance;
gboolean linear;
GimpDrawable *drawable;
GimpHistogram *histogram;
GimpHistogram *bg_histogram;
......
......@@ -589,11 +589,23 @@ HELP
if (success)
{
GimpHistogram *histogram = gimp_histogram_new (TRUE);
gint start = start_range;
gint end = end_range;
GimpHistogram *histogram;
gint start = start_range;
gint end = end_range;
gboolean precision_enabled;
gboolean linear;
gint n_bins;
precision_enabled =
gimp->plug_in_manager->current_plug_in &&
gimp_plug_in_precision_enabled (gimp->plug_in_manager->current_plug_in);
if (precision_enabled)
linear = gimp_drawable_get_linear (drawable);
else
linear = FALSE;
histogram = gimp_histogram_new (linear);
gimp_drawable_calculate_histogram (drawable, histogram);
n_bins = gimp_histogram_n_bins (histogram);
......@@ -617,9 +629,7 @@ HELP
g_object_unref (histogram);
if (n_bins == 256 ||
! gimp->plug_in_manager->current_plug_in ||
! gimp_plug_in_precision_enabled (gimp->plug_in_manager->current_plug_in))
if (n_bins == 256 || ! precision_enabled)
{
mean *= 255;
std_dev *= 255;
......
......@@ -447,11 +447,23 @@ HELP
if (success)
{
GimpHistogram *histogram = gimp_histogram_new (TRUE);
GimpHistogram *histogram;
gint n_bins;
gint start;
gboolean precision_enabled;
gboolean linear;
gint end;
precision_enabled =
gimp->plug_in_manager->current_plug_in &&
gimp_plug_in_precision_enabled (gimp->plug_in_manager->current_plug_in);
if (precision_enabled)
linear = gimp_drawable_get_linear (drawable);
else
linear = FALSE;
histogram = gimp_histogram_new (linear);
gimp_drawable_calculate_histogram (drawable, histogram);
n_bins = gimp_histogram_n_bins (histogram);
......@@ -472,9 +484,7 @@ HELP
g_object_unref (histogram);
if (n_bins == 256 ||
! gimp->plug_in_manager->current_plug_in ||
! gimp_plug_in_precision_enabled (gimp->plug_in_manager->current_plug_in))
if (n_bins == 256 || ! precision_enabled)
{
mean *= 255;
std_dev *= 255;
......
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