From: Christophe CURIS <[email protected]>
The equality comparison (a == b) is known to be a dangerous trap
when floating-point arithmetics are involved. This patch changes
all the cases which try to do this to a safer check.
---
wrlib/png.c | 2 +-
wrlib/rotate.c | 21 +++++++++++++++++----
wrlib/scale.c | 14 +++++++++++++-
3 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/wrlib/png.c b/wrlib/png.c
index fed178e..03074ea 100644
--- a/wrlib/png.c
+++ b/wrlib/png.c
@@ -140,7 +140,7 @@ RImage *RLoadPNG(RContext *context, const char *file)
sgamma = (context->attribs->rgamma + context->attribs->ggamma +
context->attribs->bgamma) / 3;
} else if ((tmp = getenv("DISPLAY_GAMMA")) != NULL) {
sgamma = atof(tmp);
- if (sgamma == 0)
+ if (sgamma < 1.0E-3)
sgamma = 1;
} else {
/* blah */
diff --git a/wrlib/rotate.c b/wrlib/rotate.c
index b1379ba..d296815 100644
--- a/wrlib/rotate.c
+++ b/wrlib/rotate.c
@@ -43,12 +43,23 @@ RImage *RRotateImage(RImage * image, float angle)
int x, y;
int bpp = image->format == RRGBAFormat ? 4 : 3;
+ /*
+ * Angle steps below this value would represent a rotation
+ * of less than 1 pixel for a 4k wide image, so not worth
+ * bothering the difference. That makes it a perfect
+ * candidate for an Epsilon when trying to compare angle
+ * to known values
+ */
+ static const float min_usable_angle = 0.00699;
+
angle = ((int)angle % 360) + (angle - (int)angle);
- if (angle == 0.0) {
+ if (angle < min_usable_angle) {
+ /* Rotate by 0 degree */
return RCloneImage(image);
- } else if (angle == 90.0) {
+ } else if ((angle > 90.0 - min_usable_angle) &&
+ (angle < 90.0 + min_usable_angle)) {
nwidth = image->height;
nheight = image->width;
@@ -91,7 +102,8 @@ RImage *RRotateImage(RImage * image, float angle)
}
}
}
- } else if (angle == 180.0) {
+ } else if ((angle > 180.0 - min_usable_angle) &&
+ (angle < 180.0 + min_usable_angle)) {
nwidth = image->width;
nheight = image->height;
@@ -129,7 +141,8 @@ RImage *RRotateImage(RImage * image, float angle)
nptr--;
}
}
- } else if (angle == 270.0) {
+ } else if ((angle > 270.0 - min_usable_angle) &&
+ (angle < 270.0 + min_usable_angle)) {
nwidth = image->height;
nheight = image->width;
diff --git a/wrlib/scale.c b/wrlib/scale.c
index 6990afe..d2cc1e6 100644
--- a/wrlib/scale.c
+++ b/wrlib/scale.c
@@ -187,8 +187,20 @@ static double B_spline_filter(double t) /* box (*) box
(*) box (*) box */
static double sinc(double x)
{
+ /*
+ * The original code did this:
+ * if (x != 0) ...
+ * This code is unsafe, it should be:
+ * if (fabs(x) > EPSILON) ...
+ *
+ * But the call to fabs is already done in the *ONLY* function
+ * that call sinc: 'Lanczos3_filter'
+ *
+ * The goal was to avoid a Divide-by-0 error, now we also
+ * avoid a +/-inf result too
+ */
x *= PI;
- if (x != 0)
+ if (x > 1.0E-9)
return (sin(x) / x);
return (1.0);
}
--
1.7.10.4
--
To unsubscribe, send mail to [email protected].