summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2013-01-18 14:13:21 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2013-01-29 15:23:05 -0500
commit1fa67f499d3826fad8783684bb90c8aadd9f682f (patch)
tree02fde397e3d0da8c82376affca946ad5e77ee01a
parent7e53e5866458fe592fc109cb1455c21c4b61dee9 (diff)
pixman-combine-float.c: Use IS_ZERO() in clip_color() and set_sat()
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.
-rw-r--r--pixman/pixman-combine-float.c30
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;