]> git.sesse.net Git - ffmpeg/blobdiff - libavutil/eval.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavutil / eval.c
index 9271fd6cbcfa59aa0adb0b551856ece816cae054..066bf7bab5bad4973c6dadad5adfa4af5ee4c94b 100644 (file)
@@ -26,8 +26,9 @@
  * see http://joe.hotchkiss.com/programming/eval/eval.html
  */
 
-#include "libavutil/avutil.h"
+#include "avutil.h"
 #include "eval.h"
+#include "log.h"
 
 typedef struct Parser {
     const AVClass *class;
@@ -76,7 +77,7 @@ double av_strtod(const char *numstr, char **tail)
     double d;
     char *next;
     if(numstr[0]=='0' && (numstr[1]|0x20)=='x') {
-        d = strtol(numstr, &next, 16);
+        d = strtoul(numstr, &next, 16);
     } else
         d = strtod(numstr, &next);
     /* if parsing succeeded, check for and interpret postfixes */
@@ -125,7 +126,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_sqrt, e_not,
     } type;
     double value; // is sign in other types
     union {
@@ -153,6 +154,7 @@ static double eval_expr(Parser *p, AVExpr *e)
         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]))
@@ -288,6 +290,8 @@ static int parse_primary(AVExpr **e, Parser *p)
     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 if (strmatch(next, "pow"   )) d->type = e_pow;
     else {
         for (i=0; p->func1_names && p->func1_names[i]; i++) {
             if (strmatch(next, p->func1_names[i])) {
@@ -456,6 +460,7 @@ static int verify_expr(AVExpr *e)
         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]);
     }
@@ -467,7 +472,7 @@ int av_expr_parse(AVExpr **expr, const char *s,
                   const char * const *func2_names, double (* const *funcs2)(void *, double, double),
                   int log_offset, void *log_ctx)
 {
-    Parser p;
+    Parser p = { 0 };
     AVExpr *e = NULL;
     char *w = av_malloc(strlen(s) + 1);
     char *wp = w;
@@ -512,7 +517,7 @@ end:
 
 double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
 {
-    Parser p;
+    Parser p = { 0 };
 
     p.const_values = const_values;
     p.opaque     = opaque;
@@ -571,6 +576,8 @@ void av_free_expr(AVExpr *e)
 
 #ifdef TEST
 #undef printf
+#include <string.h>
+
 static double const_values[] = {
     M_PI,
     M_E,
@@ -583,7 +590,7 @@ static const char *const_names[] = {
     0
 };
 
-int main(void)
+int main(int argc, char **argv)
 {
     int i;
     double d;
@@ -637,6 +644,13 @@ int main(void)
         "ceil(-123.123)",
         "sqrt(1764)",
         "sqrt(-1)",
+        "not(1)",
+        "not(NAN)",
+        "not(0)",
+        "pow(0,1.23)",
+        "pow(PI,1.23)",
+        "PI^1.23",
+        "pow(-1,1.23)",
         NULL
     };
 
@@ -657,13 +671,16 @@ int main(void)
                            NULL, NULL, NULL, NULL, NULL, 0, NULL);
     printf("%f == 0.931322575\n", d);
 
-    for (i=0; i<1050; i++) {
-        START_TIMER
+    if (argc > 1 && !strcmp(argv[1], "-t")) {
+        for (i = 0; i < 1050; i++) {
+            START_TIMER;
             av_expr_parse_and_eval(&d, "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
                                    const_names, const_values,
                                    NULL, NULL, NULL, NULL, NULL, 0, NULL);
-        STOP_TIMER("av_expr_parse_and_eval")
+            STOP_TIMER("av_expr_parse_and_eval");
+        }
     }
+
     return 0;
 }
 #endif