]> git.sesse.net Git - ffmpeg/blobdiff - libavutil/eval.c
ARM: allow runtime masking of CPU features
[ffmpeg] / libavutil / eval.c
index 4d55f42664ebe0da7f137d1cb7c024da504627c1..4d8ebf4f6e07f1c93c9f10d1a6cb7dc87cc06afe 100644 (file)
@@ -123,6 +123,7 @@ struct AVExpr {
         e_mod, e_max, e_min, e_eq, e_gt, e_gte,
         e_pow, e_mul, e_div, e_add,
         e_last, e_st, e_while, e_floor, e_ceil, e_trunc,
+        e_sqrt, e_not,
     } type;
     double value; // is sign in other types
     union {
@@ -149,6 +150,8 @@ static double eval_expr(Parser *p, AVExpr *e)
         case e_floor:  return e->value * floor(eval_expr(p, e->param[0]));
         case e_ceil :  return e->value * ceil (eval_expr(p, e->param[0]));
         case e_trunc:  return e->value * trunc(eval_expr(p, e->param[0]));
+        case e_sqrt:   return e->value * sqrt (eval_expr(p, e->param[0]));
+        case e_not:    return e->value * eval_expr(p, e->param[0]) == 0;
         case e_while: {
             double d = NAN;
             while (eval_expr(p, e->param[0]))
@@ -283,6 +286,8 @@ static int parse_primary(AVExpr **e, Parser *p)
     else if (strmatch(next, "floor" )) d->type = e_floor;
     else if (strmatch(next, "ceil"  )) d->type = e_ceil;
     else if (strmatch(next, "trunc" )) d->type = e_trunc;
+    else if (strmatch(next, "sqrt"  )) d->type = e_sqrt;
+    else if (strmatch(next, "not"   )) d->type = e_not;
     else {
         for (i=0; p->func1_names && p->func1_names[i]; i++) {
             if (strmatch(next, p->func1_names[i])) {
@@ -450,6 +455,8 @@ static int verify_expr(AVExpr *e)
         case e_floor:
         case e_ceil:
         case e_trunc:
+        case e_sqrt:
+        case e_not:
             return verify_expr(e->param[0]);
         default: return verify_expr(e->param[0]) && verify_expr(e->param[1]);
     }
@@ -489,6 +496,7 @@ int av_expr_parse(AVExpr **expr, const char *s,
     if ((ret = parse_expr(&e, &p)) < 0)
         goto end;
     if (*p.s) {
+        av_expr_free(e);
         av_log(&p, AV_LOG_ERROR, "Invalid chars '%s' at the end of expression '%s'\n", p.s, s0);
         ret = AVERROR(EINVAL);
         goto end;
@@ -535,13 +543,13 @@ int av_expr_parse_and_eval(double *d, const char *s,
 #undef printf
 #include <string.h>
 
-static double const_values[] = {
+static const double const_values[] = {
     M_PI,
     M_E,
     0
 };
 
-static const char *const_names[] = {
+static const char *const const_names[] = {
     "PI",
     "E",
     0
@@ -558,7 +566,7 @@ int main(int argc, char **argv)
         "-PI",
         "+PI",
         "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
-        "80G/80Gi"
+        "80G/80Gi",
         "1k",
         "1Gi",
         "1gi",
@@ -599,6 +607,11 @@ int main(int argc, char **argv)
         "trunc(-123.123)",
         "ceil(123.123)",
         "ceil(-123.123)",
+        "sqrt(1764)",
+        "isnan(sqrt(-1))",
+        "not(1)",
+        "not(NAN)",
+        "not(0)",
         NULL
     };