[gimp] app: return 0.0..1.0 from gimp_histogram_get_mean(), median(), std_dev()



commit 571350270bf55fd09e5a5e4f1001e1eb532b5823
Author: Michael Natterer <mitch gimp org>
Date:   Wed Jun 12 02:01:24 2013 +0200

    app: return 0.0..1.0 from gimp_histogram_get_mean(), median(), std_dev()
    
    Display the float values in the histogram dockable and add a compat
    hack to the gimp_histogram() PDB wrapper.

 app/core/gimphistogram.c          |   30 +++++++++++------
 app/core/gimphistogram.h          |    2 +-
 app/pdb/color-cmds.c              |   38 +++++++++++++++++----
 app/widgets/gimphistogrameditor.c |   12 +++---
 libgimp/gimpcolor_pdb.c           |   22 +++++++------
 tools/pdbgen/pdb/color.pdb        |   65 ++++++++++++++++++++++++++-----------
 6 files changed, 115 insertions(+), 54 deletions(-)
---
diff --git a/app/core/gimphistogram.c b/app/core/gimphistogram.c
index ce0be31..a13067d 100644
--- a/app/core/gimphistogram.c
+++ b/app/core/gimphistogram.c
@@ -676,14 +676,22 @@ gimp_histogram_get_mean (GimpHistogram        *histogram,
   if (channel == GIMP_HISTOGRAM_RGB)
     {
       for (i = start; i <= end; i++)
-        mean += (i * HISTOGRAM_VALUE (GIMP_HISTOGRAM_RED,   i) +
-                 i * HISTOGRAM_VALUE (GIMP_HISTOGRAM_GREEN, i) +
-                 i * HISTOGRAM_VALUE (GIMP_HISTOGRAM_BLUE,  i));
+        {
+          gdouble factor = (gdouble) i / (gdouble)  (priv->n_bins - 1);
+
+          mean += (factor * HISTOGRAM_VALUE (GIMP_HISTOGRAM_RED,   i) +
+                   factor * HISTOGRAM_VALUE (GIMP_HISTOGRAM_GREEN, i) +
+                   factor * HISTOGRAM_VALUE (GIMP_HISTOGRAM_BLUE,  i));
+        }
     }
   else
     {
       for (i = start; i <= end; i++)
-        mean += i * HISTOGRAM_VALUE (channel, i);
+        {
+          gdouble factor = (gdouble) i / (gdouble)  (priv->n_bins - 1);
+
+          mean += factor * HISTOGRAM_VALUE (channel, i);
+        }
     }
 
   count = gimp_histogram_get_count (histogram, channel, start, end);
@@ -694,7 +702,7 @@ gimp_histogram_get_mean (GimpHistogram        *histogram,
   return mean;
 }
 
-gint
+gdouble
 gimp_histogram_get_median (GimpHistogram         *histogram,
                            GimpHistogramChannel   channel,
                            gint                   start,
@@ -705,7 +713,7 @@ gimp_histogram_get_median (GimpHistogram         *histogram,
   gdouble               sum = 0.0;
   gdouble               count;
 
-  g_return_val_if_fail (GIMP_IS_HISTOGRAM (histogram), -1);
+  g_return_val_if_fail (GIMP_IS_HISTOGRAM (histogram), -1.0);
 
   priv = histogram->priv;
 
@@ -717,7 +725,7 @@ gimp_histogram_get_median (GimpHistogram         *histogram,
       start > end ||
       (channel == GIMP_HISTOGRAM_RGB && priv->n_channels < 4) ||
       (channel != GIMP_HISTOGRAM_RGB && channel >= priv->n_channels))
-    return 0;
+    return 0.0;
 
   start = CLAMP (start, 0, priv->n_bins - 1);
   end   = CLAMP (end,   0, priv->n_bins - 1);
@@ -733,7 +741,7 @@ gimp_histogram_get_median (GimpHistogram         *histogram,
                   HISTOGRAM_VALUE (GIMP_HISTOGRAM_BLUE,  i));
 
           if (sum * 2 > count)
-            return i;
+            return ((gdouble) i / (gdouble)  (priv->n_bins - 1));
         }
     }
   else
@@ -743,11 +751,11 @@ gimp_histogram_get_median (GimpHistogram         *histogram,
           sum += HISTOGRAM_VALUE (channel, i);
 
           if (sum * 2 > count)
-            return i;
+            return ((gdouble) i / (gdouble)  (priv->n_bins - 1));
         }
     }
 
-  return -1;
+  return -1.0;
 }
 
 /*
@@ -897,7 +905,7 @@ gimp_histogram_get_std_dev (GimpHistogram        *histogram,
           value = gimp_histogram_get_value (histogram, channel, i);
         }
 
-      dev += value * SQR (i - mean);
+      dev += value * SQR (((gdouble) i / (gdouble)  (priv->n_bins - 1)) - mean);
     }
 
   return sqrt (dev / count);
diff --git a/app/core/gimphistogram.h b/app/core/gimphistogram.h
index c8657a2..aa4abb7 100644
--- a/app/core/gimphistogram.h
+++ b/app/core/gimphistogram.h
@@ -72,7 +72,7 @@ gdouble         gimp_histogram_get_mean      (GimpHistogram        *histogram,
                                               GimpHistogramChannel  channel,
                                               gint                  start,
                                               gint                  end);
-gint            gimp_histogram_get_median    (GimpHistogram        *histogram,
+gdouble         gimp_histogram_get_median    (GimpHistogram        *histogram,
                                               GimpHistogramChannel  channel,
                                               gint                  start,
                                               gint                  end);
diff --git a/app/pdb/color-cmds.c b/app/pdb/color-cmds.c
index 9320011..05724a3 100644
--- a/app/pdb/color-cmds.c
+++ b/app/pdb/color-cmds.c
@@ -23,10 +23,13 @@
 
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
+#include "libgimpmath/gimpmath.h"
+
 #include "libgimpbase/gimpbase.h"
 
 #include "pdb-types.h"
 
+#include "core/gimp.h"
 #include "core/gimpdrawable-equalize.h"
 #include "core/gimpdrawable-histogram.h"
 #include "core/gimpdrawable-levels.h"
@@ -43,6 +46,8 @@
 #include "operations/gimplevelsconfig.h"
 #include "operations/gimpposterizeconfig.h"
 #include "operations/gimpthresholdconfig.h"
+#include "plug-in/gimpplugin.h"
+#include "plug-in/gimppluginmanager.h"
 
 #include "gimppdb.h"
 #include "gimppdb-utils.h"
@@ -614,7 +619,6 @@ histogram_invoker (GimpProcedure         *procedure,
   if (success)
     {
       if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, 0, error) ||
-          gimp_drawable_is_indexed (drawable) ||
           (! gimp_drawable_has_alpha (drawable) &&
            channel == GIMP_HISTOGRAM_ALPHA) ||
           (gimp_drawable_is_gray (drawable) &&
@@ -624,21 +628,41 @@ histogram_invoker (GimpProcedure         *procedure,
       if (success)
         {
           GimpHistogram *histogram = gimp_histogram_new (TRUE);
+          gint           start     = start_range;
+          gint           end       = end_range;
+          gint           n_bins;
 
           gimp_drawable_calculate_histogram (drawable, histogram);
 
+          n_bins = gimp_histogram_n_bins (histogram);
+
+          if (n_bins != 256)
+            {
+              start = ROUND ((gdouble) start * (n_bins - 1) / 255);
+              end   = ROUND ((gdouble) end   * (n_bins - 1) / 255);
+            }
+
           mean       = gimp_histogram_get_mean (histogram, channel,
-                                                 start_range, end_range);
+                                                 start, end);
           std_dev    = gimp_histogram_get_std_dev (histogram, channel,
-                                                   start_range, end_range);
+                                                   start, end);
           median     = gimp_histogram_get_median (histogram, channel,
-                                                  start_range, end_range);
-          pixels     = gimp_histogram_get_count (histogram, channel, 0, 255);
+                                                  start, end);
+          pixels     = gimp_histogram_get_count (histogram, channel, 0, n_bins - 1);
           count      = gimp_histogram_get_count (histogram, channel,
-                                                 start_range, end_range);
+                                                 start, end);
           percentile = count / pixels;
 
           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))
+            {
+              mean    *= 255;
+              std_dev *= 255;
+              median  *= 255;
+            }
         }
     }
 
@@ -1217,7 +1241,7 @@ register_color_procs (GimpPDB *pdb)
   gimp_procedure_set_static_strings (procedure,
                                      "gimp-histogram",
                                      "Returns information on the intensity histogram for the specified 
drawable.",
-                                     "This tool makes it possible to gather information about the intensity 
histogram of a drawable. A channel to examine is first specified. This can be either value, red, green, or 
blue, depending on whether the drawable is of type color or grayscale. The drawable may not be indexed. 
Second, a range of intensities are specified. The 'gimp-histogram' function returns statistics based on the 
pixels in the drawable that fall under this range of values. Mean, standard deviation, median, number of 
pixels, and percentile are all returned. Additionally, the total count of pixels in the image is returned. 
Counts of pixels are weighted by any associated alpha values and by the current selection mask. That is, 
pixels that lie outside an active selection mask will not be counted. Similarly, pixels with transparent 
alpha values will not be counted.",
+                                     "This tool makes it possible to gather information about the intensity 
histogram of a drawable. A channel to examine is first specified. This can be either value, red, green, or 
blue, depending on whether the drawable is of type color or grayscale. Second, a range of intensities are 
specified. The 'gimp-histogram' function returns statistics based on the pixels in the drawable that fall 
under this range of values. Mean, standard deviation, median, number of pixels, and percentile are all 
returned. Additionally, the total count of pixels in the image is returned. Counts of pixels are weighted by 
any associated alpha values and by the current selection mask. That is, pixels that lie outside an active 
selection mask will not be counted. Similarly, pixels with transparent alpha values will not be counted. The 
returned mean, std_dev and median are in the range (0..255) for 8-bit images, or if the plug-in is not 
precision-aware, and in the rang
 e (0.0..1.0) otherwise.",
                                      "Spencer Kimball & Peter Mattis",
                                      "Spencer Kimball & Peter Mattis",
                                      "1995-1996",
diff --git a/app/widgets/gimphistogrameditor.c b/app/widgets/gimphistogrameditor.c
index b2dcde3..5ee8272 100644
--- a/app/widgets/gimphistogrameditor.c
+++ b/app/widgets/gimphistogrameditor.c
@@ -527,20 +527,20 @@ gimp_histogram_editor_info_update (GimpHistogramEditor *editor)
       count  = gimp_histogram_get_count (hist, view->channel,
                                          view->start, view->end);
 
-      g_snprintf (text, sizeof (text), "%.1f",
+      g_snprintf (text, sizeof (text), "%.3f",
                   gimp_histogram_get_mean (hist, view->channel,
                                            view->start, view->end));
       gtk_label_set_text (GTK_LABEL (editor->labels[0]), text);
 
-      g_snprintf (text, sizeof (text), "%.1f",
+      g_snprintf (text, sizeof (text), "%.3f",
                   gimp_histogram_get_std_dev (hist, view->channel,
                                               view->start, view->end));
       gtk_label_set_text (GTK_LABEL (editor->labels[1]), text);
 
-      g_snprintf (text, sizeof (text), "%.1f",
-                  (gdouble) gimp_histogram_get_median  (hist, view->channel,
-                                                        view->start,
-                                                        view->end));
+      g_snprintf (text, sizeof (text), "%.3f",
+                  gimp_histogram_get_median  (hist, view->channel,
+                                              view->start,
+                                              view->end));
       gtk_label_set_text (GTK_LABEL (editor->labels[2]), text);
 
       g_snprintf (text, sizeof (text), "%d", (gint) pixels);
diff --git a/libgimp/gimpcolor_pdb.c b/libgimp/gimpcolor_pdb.c
index cc4bc0f..a5caf8b 100644
--- a/libgimp/gimpcolor_pdb.c
+++ b/libgimp/gimpcolor_pdb.c
@@ -557,16 +557,18 @@ gimp_colorize (gint32  drawable_ID,
  * This tool makes it possible to gather information about the
  * intensity histogram of a drawable. A channel to examine is first
  * specified. This can be either value, red, green, or blue, depending
- * on whether the drawable is of type color or grayscale. The drawable
- * may not be indexed. Second, a range of intensities are specified.
- * The gimp_histogram() function returns statistics based on the pixels
- * in the drawable that fall under this range of values. Mean, standard
- * deviation, median, number of pixels, and percentile are all
- * returned. Additionally, the total count of pixels in the image is
- * returned. Counts of pixels are weighted by any associated alpha
- * values and by the current selection mask. That is, pixels that lie
- * outside an active selection mask will not be counted. Similarly,
- * pixels with transparent alpha values will not be counted.
+ * on whether the drawable is of type color or grayscale. Second, a
+ * range of intensities are specified. The gimp_histogram() function
+ * returns statistics based on the pixels in the drawable that fall
+ * under this range of values. Mean, standard deviation, median, number
+ * of pixels, and percentile are all returned. Additionally, the total
+ * count of pixels in the image is returned. Counts of pixels are
+ * weighted by any associated alpha values and by the current selection
+ * mask. That is, pixels that lie outside an active selection mask will
+ * not be counted. Similarly, pixels with transparent alpha values will
+ * not be counted. The returned mean, std_dev and median are in the
+ * range (0..255) for 8-bit images, or if the plug-in is not
+ * precision-aware, and in the range (0.0..1.0) otherwise.
  *
  * Returns: TRUE on success.
  **/
diff --git a/tools/pdbgen/pdb/color.pdb b/tools/pdbgen/pdb/color.pdb
index 2ba337e..55bec29 100644
--- a/tools/pdbgen/pdb/color.pdb
+++ b/tools/pdbgen/pdb/color.pdb
@@ -627,17 +627,21 @@ Returns information on the intensity histogram for the specified drawable.
 BLURB
 
     $help = <<'HELP';
-This tool makes it possible to gather information about the intensity histogram
-of a drawable. A channel to examine is first specified. This can be either
-value, red, green, or blue, depending on whether the drawable is of type color
-or grayscale. The drawable may not be indexed. Second, a range of intensities
-are specified. The gimp_histogram() function returns statistics based on the
-pixels in the drawable that fall under this range of values. Mean, standard
-deviation, median, number of pixels, and percentile are all returned.
-Additionally, the total count of pixels in the image is returned. Counts of
-pixels are weighted by any associated alpha values and by the current selection
-mask. That is, pixels that lie outside an active selection mask will not be
-counted. Similarly, pixels with transparent alpha values will not be counted.
+This tool makes it possible to gather information about the intensity
+histogram of a drawable. A channel to examine is first specified. This
+can be either value, red, green, or blue, depending on whether the
+drawable is of type color or grayscale. Second, a range of intensities
+are specified. The gimp_histogram() function returns statistics based
+on the pixels in the drawable that fall under this range of
+values. Mean, standard deviation, median, number of pixels, and
+percentile are all returned.  Additionally, the total count of pixels
+in the image is returned. Counts of pixels are weighted by any
+associated alpha values and by the current selection mask. That is,
+pixels that lie outside an active selection mask will not be
+counted. Similarly, pixels with transparent alpha values will not be
+counted. The returned mean, std_dev and median are in the range (0..255)
+for 8-bit images, or if the plug-in is not precision-aware, and in the
+range (0.0..1.0) otherwise.
 HELP
 
     &std_pdb_misc;
@@ -674,7 +678,6 @@ HELP
        code => <<'CODE'
 {
   if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, 0, error) ||
-      gimp_drawable_is_indexed (drawable) ||
       (! gimp_drawable_has_alpha (drawable) &&
        channel == GIMP_HISTOGRAM_ALPHA) ||
       (gimp_drawable_is_gray (drawable) &&
@@ -683,22 +686,42 @@ HELP
 
   if (success)
     {
-      GimpHistogram *histogram = gimp_histogram_new ();
+      GimpHistogram *histogram = gimp_histogram_new (TRUE);
+      gint           start     = start_range;
+      gint           end       = end_range;
+      gint           n_bins;
 
       gimp_drawable_calculate_histogram (drawable, histogram);
 
+      n_bins = gimp_histogram_n_bins (histogram);
+
+      if (n_bins != 256)
+        {
+          start = ROUND ((gdouble) start * (n_bins - 1) / 255);
+          end   = ROUND ((gdouble) end   * (n_bins - 1) / 255);
+        }
+
       mean       = gimp_histogram_get_mean (histogram, channel,
-                                           start_range, end_range);
+                                           start, end);
       std_dev    = gimp_histogram_get_std_dev (histogram, channel,
-                                              start_range, end_range);
+                                              start, end);
       median     = gimp_histogram_get_median (histogram, channel,
-                                             start_range, end_range);
-      pixels     = gimp_histogram_get_count (histogram, channel, 0, 255);
+                                             start, end);
+      pixels     = gimp_histogram_get_count (histogram, channel, 0, n_bins - 1);
       count      = gimp_histogram_get_count (histogram, channel,
-                                             start_range, end_range);
+                                             start, end);
       percentile = count / pixels;
 
       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))
+        {
+          mean    *= 255;
+          std_dev *= 255;
+          median  *= 255;
+        }
     }
 }
 CODE
@@ -811,8 +834,12 @@ CODE
 }
 
 
- headers = qw("core/gimpdrawable.h"
+ headers = qw("libgimpmath/gimpmath.h"
+              "core/gimp.h"
+              "core/gimpdrawable.h"
               "core/gimpdrawable-operation.h"
+              "plug-in/gimpplugin.h"
+              "plug-in/gimppluginmanager.h"
               "gimppdb-utils.h"
               "gimp-intl.h");
 


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