[Pixman] [PATCH] pixman-combine-float.c: Use IS_ZERO() in clip_color() and set_sat()
Søren Sandmann
sandmann at cs.au.dk
Fri Jan 25 09:16:43 PST 2013
From: Søren Sandmann Pedersen <ssp at redhat.com>
The clip_color() function has some checks to avoid division by zero,
but they are done by comparing the value to 4 * FLT_EPSILON, where a
better choice is the IS_ZERO() macro that compares to +/- FLT_MIN.
In set_sat(), the check is that *max > *min before dividing by *max -
*min, but that has the potential problem that interactions between GCC
optimizions and 80 bit x87 registers could mean that (*max > *min) is
true in 80 bits, but (*max - *min) is 0 in 32 bits, so that the
division by zero is not prevented. Using IS_ZERO() here as well
prevents this.
---
pixman/pixman-combine-float.c | 30 ++++++++++++++++++------------
1 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/pixman/pixman-combine-float.c b/pixman/pixman-combine-float.c
index c916df8..06ce203 100644
--- a/pixman/pixman-combine-float.c
+++ b/pixman/pixman-combine-float.c
@@ -653,10 +653,12 @@ clip_color (rgb_t *color, float a)
float l = get_lum (color);
float n = channel_min (color);
float x = channel_max (color);
+ float t;
if (n < 0.0f)
{
- if ((l - n) < 4 * FLT_EPSILON)
+ t = l - n;
+ if (IS_ZERO (t))
{
color->r = 0.0f;
color->g = 0.0f;
@@ -664,14 +666,15 @@ clip_color (rgb_t *color, float a)
}
else
{
- color->r = l + (((color->r - l) * l) / (l - n));
- color->g = l + (((color->g - l) * l) / (l - n));
- color->b = l + (((color->b - l) * l) / (l - n));
+ color->r = l + (((color->r - l) * l) / t);
+ color->g = l + (((color->g - l) * l) / t);
+ color->b = l + (((color->b - l) * l) / t);
}
}
if (x > a)
{
- if ((x - l) < 4 * FLT_EPSILON)
+ t = x - l;
+ if (IS_ZERO (t))
{
color->r = a;
color->g = a;
@@ -679,9 +682,9 @@ clip_color (rgb_t *color, float a)
}
else
{
- color->r = l + (((color->r - l) * (a - l) / (x - l)));
- color->g = l + (((color->g - l) * (a - l) / (x - l)));
- color->b = l + (((color->b - l) * (a - l) / (x - l)));
+ color->r = l + (((color->r - l) * (a - l) / t));
+ color->g = l + (((color->g - l) * (a - l) / t));
+ color->b = l + (((color->b - l) * (a - l) / t));
}
}
}
@@ -702,6 +705,7 @@ static void
set_sat (rgb_t *src, float sat)
{
float *max, *mid, *min;
+ float t;
if (src->r > src->g)
{
@@ -752,14 +756,16 @@ set_sat (rgb_t *src, float sat)
}
}
- if (*max > *min)
+ t = *max - *min;
+
+ if (IS_ZERO (t))
{
- *mid = (((*mid - *min) * sat) / (*max - *min));
- *max = sat;
+ *mid = *max = 0.0f;
}
else
{
- *mid = *max = 0.0f;
+ *mid = ((*mid - *min) * sat) / t;
+ *max = sat;
}
*min = 0.0f;
--
1.7.4
More information about the Pixman
mailing list