void gimp_levels_config_adjust_by_colors (GimpLevelsConfig *config, GimpHistogramChannel channel, const GimpRGB *black, const GimpRGB *gray, const GimpRGB *white) { g_return_if_fail (GIMP_IS_LEVELS_CONFIG (config)); g_object_freeze_notify (G_OBJECT (config)); if (black) { config->low_input[channel] = gimp_levels_config_input_from_color (channel, black); g_object_notify (G_OBJECT (config), "low-input"); } if (white) { config->high_input[channel] = gimp_levels_config_input_from_color (channel, white); g_object_notify (G_OBJECT (config), "high-input"); } if (gray) { gdouble input; gdouble range; gdouble inten; gdouble out_light; gdouble lightness; /* Calculate lightness value */ lightness = GIMP_RGB_LUMINANCE (gray->r, gray->g, gray->b); input = gimp_levels_config_input_from_color (channel, gray); range = config->high_input[channel] - config->low_input[channel]; if (range <= 0) goto out; input -= config->low_input[channel]; if (input < 0) goto out; /* Normalize input and lightness */ inten = input / range; out_light = lightness / range; /* See bug 622054: picking pure black or white as gamma doesn't * work. But we cannot compare to 0.0 or 1.0 because cpus and * compilers are shit. If you try to check out_light using * printf() it will give exact 0.0 or 1.0 anyway, probably * because the generated code is different and out_light doesn't * live in a register. That must be why the cpu/compiler mafia * invented epsilon and defined this shit to be the programmer's * responsibility. */ if (out_light <= 0.0001 || out_light >= 0.9999) goto out; /* Map selected color to corresponding lightness */ config->gamma[channel] = log (inten) / log (out_light); config->gamma[channel] = CLAMP (config->gamma[channel], 0.1, 10.0); g_object_notify (G_OBJECT (config), "gamma"); } out: g_object_thaw_notify (G_OBJECT (config)); }
void gimp_levels_config_adjust_by_colors (GimpLevelsConfig *config, GimpHistogramChannel channel, const GimpRGB *black, const GimpRGB *gray, const GimpRGB *white) { g_return_if_fail (GIMP_IS_LEVELS_CONFIG (config)); g_object_freeze_notify (G_OBJECT (config)); if (black) { config->low_input[channel] = gimp_levels_config_input_from_color (channel, black); g_object_notify (G_OBJECT (config), "low-input"); } if (white) { config->high_input[channel] = gimp_levels_config_input_from_color (channel, white); g_object_notify (G_OBJECT (config), "high-input"); } if (gray) { gdouble input; gdouble range; gdouble inten; gdouble out_light; gdouble lightness; /* Calculate lightness value */ lightness = GIMP_RGB_LUMINANCE (gray->r, gray->g, gray->b); input = gimp_levels_config_input_from_color (channel, gray); range = config->high_input[channel] - config->low_input[channel]; if (range <= 0) return; input -= config->low_input[channel]; if (input < 0) return; /* Normalize input and lightness */ inten = input / range; out_light = lightness/ range; if (out_light <= 0) return; /* Map selected color to corresponding lightness */ config->gamma[channel] = log (inten) / log (out_light); g_object_notify (G_OBJECT (config), "gamma"); } g_object_thaw_notify (G_OBJECT (config)); }