gdouble gimp_histogram_get_channel (GimpHistogram *histogram, GimpHistogramChannel channel, gint bin) { g_return_val_if_fail (histogram != NULL, 0.0); if (histogram->n_channels > 3) channel++; return gimp_histogram_get_value (histogram, channel, bin); }
gdouble gimp_histogram_get_std_dev (GimpHistogram *histogram, GimpHistogramChannel channel, gint start, gint end) { gint i; gdouble dev = 0.0; gdouble count; gdouble mean; g_return_val_if_fail (histogram != NULL, 0.0); /* the gray alpha channel is in slot 1 */ if (histogram->n_channels == 3 && channel == GIMP_HISTOGRAM_ALPHA) channel = 1; if (! histogram->values || start > end || (channel == GIMP_HISTOGRAM_RGB && histogram->n_channels < 4) || (channel != GIMP_HISTOGRAM_RGB && channel >= histogram->n_channels)) return 0.0; mean = gimp_histogram_get_mean (histogram, channel, start, end); count = gimp_histogram_get_count (histogram, channel, start, end); if (count == 0.0) count = 1.0; for (i = start; i <= end; i++) { gdouble value; if (channel == GIMP_HISTOGRAM_RGB) { value = (HISTOGRAM_VALUE (GIMP_HISTOGRAM_RED, i) + HISTOGRAM_VALUE (GIMP_HISTOGRAM_GREEN, i) + HISTOGRAM_VALUE (GIMP_HISTOGRAM_BLUE, i)); } else { value = gimp_histogram_get_value (histogram, channel, i); } dev += value * SQR (i - mean); } return sqrt (dev / count); }
void gimp_levels_config_stretch_channel (GimpLevelsConfig *config, GimpHistogram *histogram, GimpHistogramChannel channel) { gdouble count; gdouble bias = 0.006; gint n_bins; gint i; g_return_if_fail (GIMP_IS_LEVELS_CONFIG (config)); g_return_if_fail (histogram != NULL); g_object_freeze_notify (G_OBJECT (config)); config->gamma[channel] = 1.0; config->low_output[channel] = 0.0; config->high_output[channel] = 1.0; n_bins = gimp_histogram_n_bins (histogram); count = gimp_histogram_get_count (histogram, channel, 0, n_bins - 1); if (count == 0.0) { config->low_input[channel] = 0.0; config->high_input[channel] = 0.0; } else { gdouble new_count; gdouble percentage; gdouble next_percentage; /* Set the low input */ new_count = 0.0; for (i = 0; i < (n_bins - 1); i++) { new_count += gimp_histogram_get_value (histogram, channel, i); percentage = new_count / count; next_percentage = (new_count + gimp_histogram_get_value (histogram, channel, i + 1)) / count; if (fabs (percentage - bias) < fabs (next_percentage - bias)) { config->low_input[channel] = (gdouble) (i + 1) / (n_bins - 1); break; } } /* Set the high input */ new_count = 0.0; for (i = (n_bins - 1); i > 0; i--) { new_count += gimp_histogram_get_value (histogram, channel, i); percentage = new_count / count; next_percentage = (new_count + gimp_histogram_get_value (histogram, channel, i - 1)) / count; if (fabs (percentage - bias) < fabs (next_percentage - bias)) { config->high_input[channel] = (gdouble) (i - 1) / (n_bins - 1); break; } } } g_object_notify (G_OBJECT (config), "gamma"); g_object_notify (G_OBJECT (config), "low-input"); g_object_notify (G_OBJECT (config), "high-input"); g_object_notify (G_OBJECT (config), "low-output"); g_object_notify (G_OBJECT (config), "high-output"); g_object_thaw_notify (G_OBJECT (config)); }
static void gimp_histogram_view_draw_spike (GimpHistogramView *view, GimpHistogramChannel channel, GdkGC *gc, GdkGC *bg_gc, gint x, gint i, gint j, gdouble max, gdouble bg_max, gint height, gint border) { gdouble value = 0.0; gdouble bg_value = 0.0; gint y; gint bg_y; if (view->histogram) { do { gdouble v = gimp_histogram_get_value (view->histogram, channel, i++); if (v > value) value = v; } while (i < j); } if (bg_gc && view->bg_histogram) { do { gdouble v = gimp_histogram_get_value (view->bg_histogram, channel, i++); if (v > bg_value) bg_value = v; } while (i < j); } if (value <= 0.0 && bg_value <= 0.0) return; switch (view->scale) { case GIMP_HISTOGRAM_SCALE_LINEAR: y = (gint) (((height - 2) * value) / max); bg_y = (gint) (((height - 2) * bg_value) / bg_max); break; case GIMP_HISTOGRAM_SCALE_LOGARITHMIC: y = (gint) (((height - 2) * log (value)) / max); bg_y = (gint) (((height - 2) * log (bg_value)) / bg_max); break; default: y = 0; bg_y = 0; break; } if (bg_gc) gdk_draw_line (GTK_WIDGET (view)->window, bg_gc, x + border, height + border - 1, x + border, height + border - bg_y - 1); gdk_draw_line (GTK_WIDGET (view)->window, gc, x + border, height + border - 1, x + border, height + border - y - 1); }