[FFmpeg-devel] [PATCHv2] configure+libm.h: add hypot emulation
Ganesh Ajjanagadde
gajjanagadde at gmail.com
Sun Nov 15 16:03:37 CET 2015
It is known that the naive sqrt(x*x + y*y) approach for computing the
hypotenuse suffers from overflow and accuracy issues, see e.g
http://www.johndcook.com/blog/2010/06/02/whats-so-hard-about-finding-a-hypotenuse/.
This adds hypot support to FFmpeg, a C99 function.
On platforms without hypot, this patch does a reaonable workaround, that
although not as accurate as GNU libm, is readable and does not suffer
from the overflow issue. Improvements can be made separately.
Signed-off-by: Ganesh Ajjanagadde <gajjanagadde at gmail.com>
---
configure | 2 ++
libavutil/libm.h | 23 +++++++++++++++++++++++
2 files changed, 25 insertions(+)
diff --git a/configure b/configure
index d518b21..45df724 100755
--- a/configure
+++ b/configure
@@ -1774,6 +1774,7 @@ MATH_FUNCS="
exp2
exp2f
expf
+ hypot
isinf
isnan
ldexpf
@@ -5309,6 +5310,7 @@ disabled crystalhd || check_lib libcrystalhd/libcrystalhd_if.h DtsCrystalHDVersi
atan2f_args=2
copysign_args=2
+hypot_args=2
ldexpf_args=2
powf_args=2
diff --git a/libavutil/libm.h b/libavutil/libm.h
index 6c17b28..f7a2b41 100644
--- a/libavutil/libm.h
+++ b/libavutil/libm.h
@@ -102,6 +102,29 @@ static av_always_inline av_const int isnan(float x)
}
#endif /* HAVE_ISNAN */
+#if !HAVE_HYPOT
+#undef hypot
+static inline av_const double hypot(double x, double y)
+{
+ double ret, temp;
+ x = fabs(x);
+ y = fabs(y);
+
+ if (isinf(x) || isinf(y))
+ return av_int2double(0x7ff0000000000000);
+ if (x == 0 || y == 0)
+ return x + y;
+ if (x < y) {
+ temp = x;
+ x = y;
+ y = temp;
+ }
+
+ y = y/x;
+ return x*sqrt(1 + y*y);
+}
+#endif /* HAVE_HYPOT */
+
#if !HAVE_LDEXPF
#undef ldexpf
#define ldexpf(x, exp) ((float)ldexp(x, exp))
--
2.6.2
More information about the ffmpeg-devel
mailing list