Commit c865d8f1 authored by Michael Natterer's avatar Michael Natterer 😴

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).
parent 71c88aeb
......@@ -562,24 +562,35 @@ gimp_levels_config_adjust_by_colors (GimpLevelsConfig *config,
range = config->high_input[channel] - config->low_input[channel];
if (range <= 0)
return;
goto out;
input -= config->low_input[channel];
if (input < 0)
return;
goto out;
/* Normalize input and lightness */
inten = input / range;
out_light = lightness/ range;
if (out_light <= 0)
return;
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));
}
......
......@@ -27,6 +27,8 @@
#include "core/gimpimage.h"
#include "core/gimplayer.h"
#include "operations/gimplevelsconfig.h"
#include "tests.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);
}
/**
* 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
main (int argc,
char **argv)
......@@ -242,6 +277,7 @@ main (int argc,
ADD_IMAGE_TEST (add_layer);
ADD_IMAGE_TEST (remove_layer);
ADD_IMAGE_TEST (rotate_non_overlapping);
ADD_TEST (white_graypoint_in_red_levels);
/* Run the tests */
result = g_test_run ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment