From: Christophe CURIS <christophe.cu...@free.fr>

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 wmaker-dev-unsubscr...@lists.windowmaker.org.

Reply via email to