From 5d07620d581a418290c41abefa151b8f3643f284 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Wed, 23 Jan 2008 08:48:29 +0000 Subject: [PATCH] new utility function which maps a single value. 2008-01-23 Michael Natterer * app/gegl/gimpoperationlevels.[ch] (gimp_operation_levels_map_input): new utility function which maps a single value. * app/tools/gimplevelstool.[ch] (levels_update_adjustments): use the new function to create the input arrays for gimp_color_bar_set_buffer(). Removed the Levels struct from the GimpLevelsTool struct and only use it in map() when needed. * app/base/levels.[ch]: remove obsolete API and struct members. svn path=/trunk/; revision=24682 --- ChangeLog | 14 ++++++++ app/base/levels.c | 34 ------------------- app/base/levels.h | 13 +++---- app/gegl/gimpoperationlevels.c | 28 +++++++++++++++ app/gegl/gimpoperationlevels.h | 6 +++- app/tools/gimplevelstool.c | 62 +++++++++++++++++++++++----------- app/tools/gimplevelstool.h | 1 - 7 files changed, 94 insertions(+), 64 deletions(-) diff --git a/ChangeLog b/ChangeLog index e8c46e67ce..775afdb957 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2008-01-23 Michael Natterer + + * app/gegl/gimpoperationlevels.[ch] + (gimp_operation_levels_map_input): new utility function which maps + a single value. + + * app/tools/gimplevelstool.[ch] (levels_update_adjustments): use the + new function to create the input arrays for gimp_color_bar_set_buffer(). + + Removed the Levels struct from the GimpLevelsTool struct and only + use it in map() when needed. + + * app/base/levels.[ch]: remove obsolete API and struct members. + 2008-01-22 Sven Neumann * app/core/gimpprojection.c (gimp_projection_idle_render_init): diff --git a/app/base/levels.c b/app/base/levels.c index efefbcbf07..a4669647a5 100644 --- a/app/base/levels.c +++ b/app/base/levels.c @@ -51,40 +51,6 @@ levels_init (Levels *levels) } } -void -levels_calculate_transfers (Levels *levels) -{ - gdouble inten; - gint i, j; - - g_return_if_fail (levels != NULL); - - /* Recalculate the levels arrays */ - for (j = 0; j < 5; j++) - { - for (i = 0; i < 256; i++) - { - /* determine input intensity */ - if (levels->high_input[j] != levels->low_input[j]) - { - inten = ((gdouble) (i - levels->low_input[j]) / - (double) (levels->high_input[j] - levels->low_input[j])); - } - else - { - inten = (gdouble) (i - levels->low_input[j]); - } - - inten = CLAMP (inten, 0.0, 1.0); - - if (levels->gamma[j] != 0.0) - inten = pow (inten, (1.0 / levels->gamma[j])); - - levels->input[j][i] = (guchar) (inten * 255.0 + 0.5); - } - } -} - gfloat levels_lut_func (Levels *levels, gint n_channels, diff --git a/app/base/levels.h b/app/base/levels.h index 72bea583af..d36aeb3595 100644 --- a/app/base/levels.h +++ b/app/base/levels.h @@ -29,17 +29,14 @@ struct _Levels gint low_output[5]; gint high_output[5]; - - guchar input[5][256]; /* this is used only by the gui */ }; -void levels_init (Levels *levels); -void levels_calculate_transfers (Levels *levels); -gfloat levels_lut_func (Levels *levels, - gint n_channels, - gint channel, - gfloat value); +void levels_init (Levels *levels); +gfloat levels_lut_func (Levels *levels, + gint n_channels, + gint channel, + gfloat value); #endif /* __LEVELS_H__ */ diff --git a/app/gegl/gimpoperationlevels.c b/app/gegl/gimpoperationlevels.c index 0bfe7ffdd4..0cc054f9b8 100644 --- a/app/gegl/gimpoperationlevels.c +++ b/app/gegl/gimpoperationlevels.c @@ -225,3 +225,31 @@ gimp_operation_levels_process (GeglOperation *operation, return TRUE; } + + +/* public functions */ + +gdouble +gimp_operation_levels_map_input (GimpLevelsConfig *config, + GimpHistogramChannel channel, + gdouble value) +{ + g_return_val_if_fail (GIMP_IS_LEVELS_CONFIG (config), 0.0); + + /* determine input intensity */ + if (config->high_input[channel] != config->low_input[channel]) + value = ((value - config->low_input[channel]) / + (config->high_input[channel] - config->low_input[channel])); + else + value = (value - config->low_input[channel]); + + value = CLAMP (value, 0.0, 1.0); + + if (config->gamma[channel] != 0.0) + { + value = pow (value, 1.0 / config->gamma[channel]); + } + + return value; +} + diff --git a/app/gegl/gimpoperationlevels.h b/app/gegl/gimpoperationlevels.h index b17afb790d..2aa084661c 100644 --- a/app/gegl/gimpoperationlevels.h +++ b/app/gegl/gimpoperationlevels.h @@ -50,7 +50,11 @@ struct _GimpOperationLevelsClass }; -GType gimp_operation_levels_get_type (void) G_GNUC_CONST; +GType gimp_operation_levels_get_type (void) G_GNUC_CONST; + +gdouble gimp_operation_levels_map_input (GimpLevelsConfig *config, + GimpHistogramChannel channel, + gdouble value); #endif /* __GIMP_OPERATION_LEVELS_H__ */ diff --git a/app/tools/gimplevelstool.c b/app/tools/gimplevelstool.c index 0592a88bc7..7395d34599 100644 --- a/app/tools/gimplevelstool.c +++ b/app/tools/gimplevelstool.c @@ -38,6 +38,7 @@ #include "base/levels.h" #include "gegl/gimplevelsconfig.h" +#include "gegl/gimpoperationlevels.h" #include "core/gimpdrawable.h" #include "core/gimpdrawable-histogram.h" @@ -180,13 +181,10 @@ gimp_levels_tool_init (GimpLevelsTool *tool) GimpImageMapTool *im_tool = GIMP_IMAGE_MAP_TOOL (tool); tool->lut = gimp_lut_new (); - tool->levels = g_slice_new0 (Levels); tool->hist = NULL; tool->channel = GIMP_HISTOGRAM_VALUE; tool->active_picker = NULL; - levels_init (tool->levels); - im_tool->apply_func = (GimpImageMapApplyFunc) gimp_lut_process; im_tool->apply_data = tool->lut; } @@ -196,15 +194,14 @@ gimp_levels_tool_finalize (GObject *object) { GimpLevelsTool *tool = GIMP_LEVELS_TOOL (object); - gimp_lut_free (tool->lut); - g_slice_free (Levels, tool->levels); - if (tool->config) { g_object_unref (tool->config); tool->config = NULL; } + gimp_lut_free (tool->lut); + if (tool->hist) { gimp_histogram_free (tool->hist); @@ -285,12 +282,13 @@ static void gimp_levels_tool_map (GimpImageMapTool *image_map_tool) { GimpLevelsTool *tool = GIMP_LEVELS_TOOL (image_map_tool); + Levels levels; - gimp_levels_config_to_levels_cruft (tool->config, tool->levels, tool->color); + gimp_levels_config_to_levels_cruft (tool->config, &levels, tool->color); gimp_lut_setup (tool->lut, (GimpLutFunc) levels_lut_func, - tool->levels, + &levels, gimp_drawable_bytes (image_map_tool->drawable)); } @@ -830,28 +828,52 @@ levels_update_adjustments (GimpLevelsTool *tool) static void levels_update_input_bar (GimpLevelsTool *tool) { - /* Recalculate the transfer arrays */ - gimp_levels_config_to_levels_cruft (tool->config, tool->levels, tool->color); - levels_calculate_transfers (tool->levels); - switch (tool->channel) { case GIMP_HISTOGRAM_VALUE: case GIMP_HISTOGRAM_ALPHA: case GIMP_HISTOGRAM_RGB: - gimp_color_bar_set_buffers (GIMP_COLOR_BAR (tool->input_bar), - tool->levels->input[tool->channel], - tool->levels->input[tool->channel], - tool->levels->input[tool->channel]); + { + guchar v[256]; + gint i; + + for (i = 0; i < 256; i++) + { + v[i] = gimp_operation_levels_map_input (tool->config, + tool->channel, + i / 255.0) * 255.999; + } + + gimp_color_bar_set_buffers (GIMP_COLOR_BAR (tool->input_bar), + v, v, v); + } break; case GIMP_HISTOGRAM_RED: case GIMP_HISTOGRAM_GREEN: case GIMP_HISTOGRAM_BLUE: - gimp_color_bar_set_buffers (GIMP_COLOR_BAR (tool->input_bar), - tool->levels->input[GIMP_HISTOGRAM_RED], - tool->levels->input[GIMP_HISTOGRAM_GREEN], - tool->levels->input[GIMP_HISTOGRAM_BLUE]); + { + guchar r[256]; + guchar g[256]; + guchar b[256]; + gint i; + + for (i = 0; i < 256; i++) + { + r[i] = gimp_operation_levels_map_input (tool->config, + GIMP_HISTOGRAM_RED, + i / 255.0) * 255.999; + g[i] = gimp_operation_levels_map_input (tool->config, + GIMP_HISTOGRAM_GREEN, + i / 255.0) * 255.999; + b[i] = gimp_operation_levels_map_input (tool->config, + GIMP_HISTOGRAM_BLUE, + i / 255.0) * 255.999; + } + + gimp_color_bar_set_buffers (GIMP_COLOR_BAR (tool->input_bar), + r, g, b); + } break; } } diff --git a/app/tools/gimplevelstool.h b/app/tools/gimplevelstool.h index fcf0693881..9797cd2c4f 100644 --- a/app/tools/gimplevelstool.h +++ b/app/tools/gimplevelstool.h @@ -40,7 +40,6 @@ struct _GimpLevelsTool GimpLevelsConfig *config; GimpLut *lut; - Levels *levels; /* dialog */ gboolean color;