mirror of https://github.com/GNOME/gimp.git
Bug 622054 - Levels Tool gray point picker causes lockup
Bail out in gimp_levels_config_adjust_by_colors() if pure back or white was picked as gray (gamma).
This commit is contained in:
parent
71c88aebdc
commit
c865d8f141
|
@ -562,24 +562,35 @@ gimp_levels_config_adjust_by_colors (GimpLevelsConfig *config,
|
||||||
|
|
||||||
range = config->high_input[channel] - config->low_input[channel];
|
range = config->high_input[channel] - config->low_input[channel];
|
||||||
if (range <= 0)
|
if (range <= 0)
|
||||||
return;
|
goto out;
|
||||||
|
|
||||||
input -= config->low_input[channel];
|
input -= config->low_input[channel];
|
||||||
if (input < 0)
|
if (input < 0)
|
||||||
return;
|
goto out;
|
||||||
|
|
||||||
/* Normalize input and lightness */
|
/* Normalize input and lightness */
|
||||||
inten = input / range;
|
inten = input / range;
|
||||||
out_light = lightness/ range;
|
out_light = lightness / range;
|
||||||
|
|
||||||
if (out_light <= 0)
|
/* See bug 622054: picking pure black or white as gamma doesn't
|
||||||
return;
|
* 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 */
|
/* Map selected color to corresponding lightness */
|
||||||
config->gamma[channel] = log (inten) / log (out_light);
|
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");
|
g_object_notify (G_OBJECT (config), "gamma");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
g_object_thaw_notify (G_OBJECT (config));
|
g_object_thaw_notify (G_OBJECT (config));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include "core/gimpimage.h"
|
#include "core/gimpimage.h"
|
||||||
#include "core/gimplayer.h"
|
#include "core/gimplayer.h"
|
||||||
|
|
||||||
|
#include "operations/gimplevelsconfig.h"
|
||||||
|
|
||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
|
|
||||||
#include "gimp-app-test-utils.h"
|
#include "gimp-app-test-utils.h"
|
||||||
|
@ -222,6 +224,39 @@ remove_layer (GimpTestFixture *fixture,
|
||||||
g_assert_cmpint (gimp_image_get_n_layers (image), ==, 0);
|
g_assert_cmpint (gimp_image_get_n_layers (image), ==, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* white_graypoint_in_red_levels:
|
||||||
|
* @fixture:
|
||||||
|
* @data:
|
||||||
|
*
|
||||||
|
* Makes sure the levels algorithm can handle when the graypoint is
|
||||||
|
* white. It's easy to get a divide by zero problem when trying to
|
||||||
|
* calculate what gamma will give a white graypoint.
|
||||||
|
**/
|
||||||
|
static void
|
||||||
|
white_graypoint_in_red_levels (GimpTestFixture *fixture,
|
||||||
|
gconstpointer data)
|
||||||
|
{
|
||||||
|
GimpRGB black = { 0, 0, 0, 0 };
|
||||||
|
GimpRGB gray = { 1, 1, 1, 1 };
|
||||||
|
GimpRGB white = { 1, 1, 1, 1 };
|
||||||
|
GimpHistogramChannel channel = GIMP_HISTOGRAM_RED;
|
||||||
|
GimpLevelsConfig *config;
|
||||||
|
|
||||||
|
config = g_object_new (GIMP_TYPE_LEVELS_CONFIG, NULL);
|
||||||
|
|
||||||
|
gimp_levels_config_adjust_by_colors (config,
|
||||||
|
channel,
|
||||||
|
&black,
|
||||||
|
&gray,
|
||||||
|
&white);
|
||||||
|
|
||||||
|
/* Make sure we didn't end up with an invalid gamma value */
|
||||||
|
g_object_set (config,
|
||||||
|
"gamma", config->gamma[channel],
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
char **argv)
|
char **argv)
|
||||||
|
@ -242,6 +277,7 @@ main (int argc,
|
||||||
ADD_IMAGE_TEST (add_layer);
|
ADD_IMAGE_TEST (add_layer);
|
||||||
ADD_IMAGE_TEST (remove_layer);
|
ADD_IMAGE_TEST (remove_layer);
|
||||||
ADD_IMAGE_TEST (rotate_non_overlapping);
|
ADD_IMAGE_TEST (rotate_non_overlapping);
|
||||||
|
ADD_TEST (white_graypoint_in_red_levels);
|
||||||
|
|
||||||
/* Run the tests */
|
/* Run the tests */
|
||||||
result = g_test_run ();
|
result = g_test_run ();
|
||||||
|
|
Loading…
Reference in New Issue