Merge commit '8a9de5c52401aa1e87bdb147524831c640d1ec53'
[ffmpeg.git] / libavutil / libm.h
index c7c28ac..6d8bd68 100644 (file)
 #include <math.h>
 #include "config.h"
 #include "attributes.h"
+#include "intfloat.h"
+
+#if HAVE_MIPSFPU && HAVE_INLINE_ASM
+#include "libavutil/mips/libm_mips.h"
+#endif /* HAVE_MIPSFPU && HAVE_INLINE_ASM*/
+
+#if !HAVE_ATANF
+#undef atanf
+#define atanf(x) ((float)atan(x))
+#endif
+
+#if !HAVE_ATAN2F
+#undef atan2f
+#define atan2f(y, x) ((float)atan2(y, x))
+#endif
+
+#if !HAVE_POWF
+#undef powf
+#define powf(x, y) ((float)pow(x, y))
+#endif
+
+#if !HAVE_CBRT
+static av_always_inline double cbrt(double x)
+{
+    return x < 0 ? -pow(-x, 1.0 / 3.0) : pow(x, 1.0 / 3.0);
+}
+#endif
+
+#if !HAVE_CBRTF
+static av_always_inline float cbrtf(float x)
+{
+    return x < 0 ? -powf(-x, 1.0 / 3.0) : powf(x, 1.0 / 3.0);
+}
+#endif
+
+#if !HAVE_COSF
+#undef cosf
+#define cosf(x) ((float)cos(x))
+#endif
+
+#if !HAVE_EXPF
+#undef expf
+#define expf(x) ((float)exp(x))
+#endif
 
 #if !HAVE_EXP2
 #undef exp2
 #define exp2f(x) ((float)exp2(x))
 #endif /* HAVE_EXP2F */
 
+#if !HAVE_ISINF
+#undef isinf
+/* Note: these do not follow the BSD/Apple/GNU convention of returning -1 for
+-Inf, +1 for Inf, 0 otherwise, but merely follow the POSIX/ISO mandated spec of
+returning a non-zero value for +/-Inf, 0 otherwise. */
+static av_always_inline av_const int avpriv_isinff(float x)
+{
+    uint32_t v = av_float2int(x);
+    if ((v & 0x7f800000) != 0x7f800000)
+        return 0;
+    return !(v & 0x007fffff);
+}
+
+static av_always_inline av_const int avpriv_isinf(double x)
+{
+    uint64_t v = av_double2int(x);
+    if ((v & 0x7ff0000000000000) != 0x7ff0000000000000)
+        return 0;
+    return !(v & 0x000fffffffffffff);
+}
+
+#define isinf(x)                  \
+    (sizeof(x) == sizeof(float)   \
+        ? avpriv_isinff(x)        \
+        : avpriv_isinf(x))
+#endif /* HAVE_ISINF */
+
+#if !HAVE_ISNAN
+static av_always_inline av_const int avpriv_isnanf(float x)
+{
+    uint32_t v = av_float2int(x);
+    if ((v & 0x7f800000) != 0x7f800000)
+        return 0;
+    return v & 0x007fffff;
+}
+
+static av_always_inline av_const int avpriv_isnan(double x)
+{
+    uint64_t v = av_double2int(x);
+    if ((v & 0x7ff0000000000000) != 0x7ff0000000000000)
+        return 0;
+    return (v & 0x000fffffffffffff) && 1;
+}
+
+#define isnan(x)                  \
+    (sizeof(x) == sizeof(float)   \
+        ? avpriv_isnanf(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))
+#endif
+
 #if !HAVE_LLRINT
 #undef llrint
 #define llrint(x) ((long long)rint(x))
 #define log2f(x) ((float)log2(x))
 #endif /* HAVE_LOG2F */
 
+#if !HAVE_LOG10F
+#undef log10f
+#define log10f(x) ((float)log10(x))
+#endif
+
+#if !HAVE_SINF
+#undef sinf
+#define sinf(x) ((float)sin(x))
+#endif
+
+#if !HAVE_RINT
+static inline double rint(double x)
+{
+    return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5);
+}
+#endif /* HAVE_RINT */
+
 #if !HAVE_LRINT
 static av_always_inline av_const long int lrint(double x)
 {
@@ -86,6 +225,13 @@ static av_always_inline av_const float roundf(float x)
 }
 #endif /* HAVE_ROUNDF */
 
+#if !HAVE_TRUNC
+static av_always_inline av_const double trunc(double x)
+{
+    return (x > 0) ? floor(x) : ceil(x);
+}
+#endif /* HAVE_TRUNC */
+
 #if !HAVE_TRUNCF
 static av_always_inline av_const float truncf(float x)
 {