diff options
author | Ganesh Ajjanagadde <gajjanagadde@gmail.com> | 2015-11-14 19:57:28 +0300 |
---|---|---|
committer | Ganesh Ajjanagadde <gajjanagadde@gmail.com> | 2015-11-21 16:51:49 +0300 |
commit | 275aca8fba50e77af16627d8d5db4b3d4987d889 (patch) | |
tree | 7b0d88db7fb09ddbe2235c5caf43a5832d580fe1 | |
parent | 14ea4151d7c3c26500193f11ac661ed20c7c2b9c (diff) |
configure+libm.h: add hypot emulation
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.
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Ganesh Ajjanagadde <gajjanagadde@gmail.com>
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | libavutil/libm.h | 23 |
2 files changed, 25 insertions, 0 deletions
@@ -1773,6 +1773,7 @@ MATH_FUNCS=" exp2 exp2f expf + hypot isinf isnan ldexpf @@ -5308,6 +5309,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 221c2867c5..9e5ec5d43c 100644 --- a/libavutil/libm.h +++ b/libavutil/libm.h @@ -132,6 +132,29 @@ static av_always_inline av_const int avpriv_isnan(double x) : avpriv_isnan(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)) |