[gimp] Bug 622054 - Levels Tool gray point picker causes lockup
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 622054 - Levels Tool gray point picker causes lockup
- Date: Wed, 27 Mar 2013 21:29:55 +0000 (UTC)
commit c865d8f1416a6917f120f7aaaa99b9aed7b0f280
Author: Michael Natterer <mitch gimp org>
Date: Wed Mar 27 22:28:29 2013 +0100
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).
app/operations/gimplevelsconfig.c | 23 +++++++++++++++++------
app/tests/test-core.c | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+), 6 deletions(-)
---
diff --git a/app/operations/gimplevelsconfig.c b/app/operations/gimplevelsconfig.c
index a6678a7..69b5e26 100644
--- a/app/operations/gimplevelsconfig.c
+++ b/app/operations/gimplevelsconfig.c
@@ -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));
}
diff --git a/app/tests/test-core.c b/app/tests/test-core.c
index efd3962..575a4d3 100644
--- a/app/tests/test-core.c
+++ b/app/tests/test-core.c
@@ -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 ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]