static void
equalize_destroy_data (gpointer user_data)
{
	EqualizeData *equalize_data = user_data;

	gth_cumulative_histogram_free (equalize_data->cumulative);
	g_free (equalize_data);
}
static void
adjust_contrast_setup (AdjustContrastData *adjust_data)
{
	GthHistogram  *histogram;
	long         **cumulative;
	int            c, v;
	glong          n_pixels;
	double         lower_threshold;
	double         higher_threshold;

	/* histogram */

	histogram = gth_histogram_new ();
	gth_histogram_calculate_for_image (histogram, adjust_data->source);
	cumulative = gth_histogram_get_cumulative (histogram);

	/* lowest and highest values for each channel */

	adjust_data->lowest = g_new (int, GTH_HISTOGRAM_N_CHANNELS);
	adjust_data->highest = g_new (int, GTH_HISTOGRAM_N_CHANNELS);

	n_pixels = cairo_image_surface_get_width (adjust_data->source) * cairo_image_surface_get_height (adjust_data->source);
	lower_threshold = HISTOGRAM_CROP * n_pixels;
	higher_threshold = (1.0 - HISTOGRAM_CROP) * n_pixels;

	for (c = 0; c < GTH_HISTOGRAM_N_CHANNELS; c++) {
		gboolean lowest_set = FALSE;

		for (v = 0; v < 256; v++) {
			if (! lowest_set && (cumulative[c][v] >= lower_threshold)) {
				adjust_data->lowest[c] = v;
				lowest_set = TRUE;
			}

			if (cumulative[c][v] <= higher_threshold)
				adjust_data->highest[c] = v;
		}
	}

	/* stretch factor */

	adjust_data->factor = g_new (double, GTH_HISTOGRAM_N_CHANNELS);
	for (c = 0; c < GTH_HISTOGRAM_N_CHANNELS; c++) {
		if (adjust_data->highest[c] != adjust_data->lowest[c])
			adjust_data->factor[c] = 255.0 / ((double) adjust_data->highest[c] - adjust_data->lowest[c]);
		else
			adjust_data->factor[c] = 0.0;
	}

	/**/

	gth_cumulative_histogram_free (cumulative);
	g_object_unref (histogram);
}