1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2002-2006 Michael Niedermayer <michaelni@gmx.at> 3cabdff1aSopenharmony_ci * Copyright (c) 2006 Oded Shimon <ods15@ods15.dyndns.org> 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci/** 23cabdff1aSopenharmony_ci * @file 24cabdff1aSopenharmony_ci * simple arithmetic expression evaluator. 25cabdff1aSopenharmony_ci * 26cabdff1aSopenharmony_ci * see http://joe.hotchkiss.com/programming/eval/eval.html 27cabdff1aSopenharmony_ci */ 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci#include <float.h> 30cabdff1aSopenharmony_ci#include "attributes.h" 31cabdff1aSopenharmony_ci#include "avutil.h" 32cabdff1aSopenharmony_ci#include "common.h" 33cabdff1aSopenharmony_ci#include "eval.h" 34cabdff1aSopenharmony_ci#include "ffmath.h" 35cabdff1aSopenharmony_ci#include "internal.h" 36cabdff1aSopenharmony_ci#include "log.h" 37cabdff1aSopenharmony_ci#include "mathematics.h" 38cabdff1aSopenharmony_ci#include "time.h" 39cabdff1aSopenharmony_ci#include "avstring.h" 40cabdff1aSopenharmony_ci#include "timer.h" 41cabdff1aSopenharmony_ci#include "reverse.h" 42cabdff1aSopenharmony_ci 43cabdff1aSopenharmony_citypedef struct Parser { 44cabdff1aSopenharmony_ci const AVClass *class; 45cabdff1aSopenharmony_ci int stack_index; 46cabdff1aSopenharmony_ci char *s; 47cabdff1aSopenharmony_ci const double *const_values; 48cabdff1aSopenharmony_ci const char * const *const_names; // NULL terminated 49cabdff1aSopenharmony_ci double (* const *funcs1)(void *, double a); // NULL terminated 50cabdff1aSopenharmony_ci const char * const *func1_names; // NULL terminated 51cabdff1aSopenharmony_ci double (* const *funcs2)(void *, double a, double b); // NULL terminated 52cabdff1aSopenharmony_ci const char * const *func2_names; // NULL terminated 53cabdff1aSopenharmony_ci void *opaque; 54cabdff1aSopenharmony_ci int log_offset; 55cabdff1aSopenharmony_ci void *log_ctx; 56cabdff1aSopenharmony_ci#define VARS 10 57cabdff1aSopenharmony_ci double *var; 58cabdff1aSopenharmony_ci} Parser; 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_cistatic const AVClass eval_class = { 61cabdff1aSopenharmony_ci .class_name = "Eval", 62cabdff1aSopenharmony_ci .item_name = av_default_item_name, 63cabdff1aSopenharmony_ci .option = NULL, 64cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 65cabdff1aSopenharmony_ci .log_level_offset_offset = offsetof(Parser, log_offset), 66cabdff1aSopenharmony_ci .parent_log_context_offset = offsetof(Parser, log_ctx), 67cabdff1aSopenharmony_ci}; 68cabdff1aSopenharmony_ci 69cabdff1aSopenharmony_cistatic const struct { 70cabdff1aSopenharmony_ci double bin_val; 71cabdff1aSopenharmony_ci double dec_val; 72cabdff1aSopenharmony_ci int8_t exp; 73cabdff1aSopenharmony_ci} si_prefixes['z' - 'E' + 1] = { 74cabdff1aSopenharmony_ci ['y'-'E']= { 8.271806125530276749e-25, 1e-24, -24 }, 75cabdff1aSopenharmony_ci ['z'-'E']= { 8.4703294725430034e-22, 1e-21, -21 }, 76cabdff1aSopenharmony_ci ['a'-'E']= { 8.6736173798840355e-19, 1e-18, -18 }, 77cabdff1aSopenharmony_ci ['f'-'E']= { 8.8817841970012523e-16, 1e-15, -15 }, 78cabdff1aSopenharmony_ci ['p'-'E']= { 9.0949470177292824e-13, 1e-12, -12 }, 79cabdff1aSopenharmony_ci ['n'-'E']= { 9.3132257461547852e-10, 1e-9, -9 }, 80cabdff1aSopenharmony_ci ['u'-'E']= { 9.5367431640625e-7, 1e-6, -6 }, 81cabdff1aSopenharmony_ci ['m'-'E']= { 9.765625e-4, 1e-3, -3 }, 82cabdff1aSopenharmony_ci ['c'-'E']= { 9.8431332023036951e-3, 1e-2, -2 }, 83cabdff1aSopenharmony_ci ['d'-'E']= { 9.921256574801246e-2, 1e-1, -1 }, 84cabdff1aSopenharmony_ci ['h'-'E']= { 1.0159366732596479e2, 1e2, 2 }, 85cabdff1aSopenharmony_ci ['k'-'E']= { 1.024e3, 1e3, 3 }, 86cabdff1aSopenharmony_ci ['K'-'E']= { 1.024e3, 1e3, 3 }, 87cabdff1aSopenharmony_ci ['M'-'E']= { 1.048576e6, 1e6, 6 }, 88cabdff1aSopenharmony_ci ['G'-'E']= { 1.073741824e9, 1e9, 9 }, 89cabdff1aSopenharmony_ci ['T'-'E']= { 1.099511627776e12, 1e12, 12 }, 90cabdff1aSopenharmony_ci ['P'-'E']= { 1.125899906842624e15, 1e15, 15 }, 91cabdff1aSopenharmony_ci ['E'-'E']= { 1.152921504606847e18, 1e18, 18 }, 92cabdff1aSopenharmony_ci ['Z'-'E']= { 1.1805916207174113e21, 1e21, 21 }, 93cabdff1aSopenharmony_ci ['Y'-'E']= { 1.2089258196146292e24, 1e24, 24 }, 94cabdff1aSopenharmony_ci}; 95cabdff1aSopenharmony_ci 96cabdff1aSopenharmony_cistatic const struct { 97cabdff1aSopenharmony_ci const char *name; 98cabdff1aSopenharmony_ci double value; 99cabdff1aSopenharmony_ci} constants[] = { 100cabdff1aSopenharmony_ci { "E", M_E }, 101cabdff1aSopenharmony_ci { "PI", M_PI }, 102cabdff1aSopenharmony_ci { "PHI", M_PHI }, 103cabdff1aSopenharmony_ci { "QP2LAMBDA", FF_QP2LAMBDA }, 104cabdff1aSopenharmony_ci}; 105cabdff1aSopenharmony_ci 106cabdff1aSopenharmony_cidouble av_strtod(const char *numstr, char **tail) 107cabdff1aSopenharmony_ci{ 108cabdff1aSopenharmony_ci double d; 109cabdff1aSopenharmony_ci char *next; 110cabdff1aSopenharmony_ci if(numstr[0]=='0' && (numstr[1]|0x20)=='x') { 111cabdff1aSopenharmony_ci d = strtoul(numstr, &next, 16); 112cabdff1aSopenharmony_ci } else 113cabdff1aSopenharmony_ci d = strtod(numstr, &next); 114cabdff1aSopenharmony_ci /* if parsing succeeded, check for and interpret postfixes */ 115cabdff1aSopenharmony_ci if (next!=numstr) { 116cabdff1aSopenharmony_ci if (next[0] == 'd' && next[1] == 'B') { 117cabdff1aSopenharmony_ci /* treat dB as decibels instead of decibytes */ 118cabdff1aSopenharmony_ci d = ff_exp10(d / 20); 119cabdff1aSopenharmony_ci next += 2; 120cabdff1aSopenharmony_ci } else if (*next >= 'E' && *next <= 'z') { 121cabdff1aSopenharmony_ci int e= si_prefixes[*next - 'E'].exp; 122cabdff1aSopenharmony_ci if (e) { 123cabdff1aSopenharmony_ci if (next[1] == 'i') { 124cabdff1aSopenharmony_ci d*= si_prefixes[*next - 'E'].bin_val; 125cabdff1aSopenharmony_ci next+=2; 126cabdff1aSopenharmony_ci } else { 127cabdff1aSopenharmony_ci d*= si_prefixes[*next - 'E'].dec_val; 128cabdff1aSopenharmony_ci next++; 129cabdff1aSopenharmony_ci } 130cabdff1aSopenharmony_ci } 131cabdff1aSopenharmony_ci } 132cabdff1aSopenharmony_ci 133cabdff1aSopenharmony_ci if (*next=='B') { 134cabdff1aSopenharmony_ci d*=8; 135cabdff1aSopenharmony_ci next++; 136cabdff1aSopenharmony_ci } 137cabdff1aSopenharmony_ci } 138cabdff1aSopenharmony_ci /* if requested, fill in tail with the position after the last parsed 139cabdff1aSopenharmony_ci character */ 140cabdff1aSopenharmony_ci if (tail) 141cabdff1aSopenharmony_ci *tail = next; 142cabdff1aSopenharmony_ci return d; 143cabdff1aSopenharmony_ci} 144cabdff1aSopenharmony_ci 145cabdff1aSopenharmony_ci#define IS_IDENTIFIER_CHAR(c) ((c) - '0' <= 9U || (c) - 'a' <= 25U || (c) - 'A' <= 25U || (c) == '_') 146cabdff1aSopenharmony_ci 147cabdff1aSopenharmony_cistatic int strmatch(const char *s, const char *prefix) 148cabdff1aSopenharmony_ci{ 149cabdff1aSopenharmony_ci int i; 150cabdff1aSopenharmony_ci for (i=0; prefix[i]; i++) { 151cabdff1aSopenharmony_ci if (prefix[i] != s[i]) return 0; 152cabdff1aSopenharmony_ci } 153cabdff1aSopenharmony_ci /* return 1 only if the s identifier is terminated */ 154cabdff1aSopenharmony_ci return !IS_IDENTIFIER_CHAR(s[i]); 155cabdff1aSopenharmony_ci} 156cabdff1aSopenharmony_ci 157cabdff1aSopenharmony_cistruct AVExpr { 158cabdff1aSopenharmony_ci enum { 159cabdff1aSopenharmony_ci e_value, e_const, e_func0, e_func1, e_func2, 160cabdff1aSopenharmony_ci e_squish, e_gauss, e_ld, e_isnan, e_isinf, 161cabdff1aSopenharmony_ci e_mod, e_max, e_min, e_eq, e_gt, e_gte, e_lte, e_lt, 162cabdff1aSopenharmony_ci e_pow, e_mul, e_div, e_add, 163cabdff1aSopenharmony_ci e_last, e_st, e_while, e_taylor, e_root, e_floor, e_ceil, e_trunc, e_round, 164cabdff1aSopenharmony_ci e_sqrt, e_not, e_random, e_hypot, e_gcd, 165cabdff1aSopenharmony_ci e_if, e_ifnot, e_print, e_bitand, e_bitor, e_between, e_clip, e_atan2, e_lerp, 166cabdff1aSopenharmony_ci e_sgn, 167cabdff1aSopenharmony_ci } type; 168cabdff1aSopenharmony_ci double value; // is sign in other types 169cabdff1aSopenharmony_ci int const_index; 170cabdff1aSopenharmony_ci union { 171cabdff1aSopenharmony_ci double (*func0)(double); 172cabdff1aSopenharmony_ci double (*func1)(void *, double); 173cabdff1aSopenharmony_ci double (*func2)(void *, double, double); 174cabdff1aSopenharmony_ci } a; 175cabdff1aSopenharmony_ci struct AVExpr *param[3]; 176cabdff1aSopenharmony_ci double *var; 177cabdff1aSopenharmony_ci}; 178cabdff1aSopenharmony_ci 179cabdff1aSopenharmony_cistatic double etime(double v) 180cabdff1aSopenharmony_ci{ 181cabdff1aSopenharmony_ci return av_gettime() * 0.000001; 182cabdff1aSopenharmony_ci} 183cabdff1aSopenharmony_ci 184cabdff1aSopenharmony_cistatic double eval_expr(Parser *p, AVExpr *e) 185cabdff1aSopenharmony_ci{ 186cabdff1aSopenharmony_ci switch (e->type) { 187cabdff1aSopenharmony_ci case e_value: return e->value; 188cabdff1aSopenharmony_ci case e_const: return e->value * p->const_values[e->const_index]; 189cabdff1aSopenharmony_ci case e_func0: return e->value * e->a.func0(eval_expr(p, e->param[0])); 190cabdff1aSopenharmony_ci case e_func1: return e->value * e->a.func1(p->opaque, eval_expr(p, e->param[0])); 191cabdff1aSopenharmony_ci case e_func2: return e->value * e->a.func2(p->opaque, eval_expr(p, e->param[0]), eval_expr(p, e->param[1])); 192cabdff1aSopenharmony_ci case e_squish: return 1/(1+exp(4*eval_expr(p, e->param[0]))); 193cabdff1aSopenharmony_ci case e_gauss: { double d = eval_expr(p, e->param[0]); return exp(-d*d/2)/sqrt(2*M_PI); } 194cabdff1aSopenharmony_ci case e_ld: return e->value * p->var[av_clip(eval_expr(p, e->param[0]), 0, VARS-1)]; 195cabdff1aSopenharmony_ci case e_isnan: return e->value * !!isnan(eval_expr(p, e->param[0])); 196cabdff1aSopenharmony_ci case e_isinf: return e->value * !!isinf(eval_expr(p, e->param[0])); 197cabdff1aSopenharmony_ci case e_floor: return e->value * floor(eval_expr(p, e->param[0])); 198cabdff1aSopenharmony_ci case e_ceil : return e->value * ceil (eval_expr(p, e->param[0])); 199cabdff1aSopenharmony_ci case e_trunc: return e->value * trunc(eval_expr(p, e->param[0])); 200cabdff1aSopenharmony_ci case e_round: return e->value * round(eval_expr(p, e->param[0])); 201cabdff1aSopenharmony_ci case e_sgn: return e->value * FFDIFFSIGN(eval_expr(p, e->param[0]), 0); 202cabdff1aSopenharmony_ci case e_sqrt: return e->value * sqrt (eval_expr(p, e->param[0])); 203cabdff1aSopenharmony_ci case e_not: return e->value * (eval_expr(p, e->param[0]) == 0); 204cabdff1aSopenharmony_ci case e_if: return e->value * (eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) : 205cabdff1aSopenharmony_ci e->param[2] ? eval_expr(p, e->param[2]) : 0); 206cabdff1aSopenharmony_ci case e_ifnot: return e->value * (!eval_expr(p, e->param[0]) ? eval_expr(p, e->param[1]) : 207cabdff1aSopenharmony_ci e->param[2] ? eval_expr(p, e->param[2]) : 0); 208cabdff1aSopenharmony_ci case e_clip: { 209cabdff1aSopenharmony_ci double x = eval_expr(p, e->param[0]); 210cabdff1aSopenharmony_ci double min = eval_expr(p, e->param[1]), max = eval_expr(p, e->param[2]); 211cabdff1aSopenharmony_ci if (isnan(min) || isnan(max) || isnan(x) || min > max) 212cabdff1aSopenharmony_ci return NAN; 213cabdff1aSopenharmony_ci return e->value * av_clipd(eval_expr(p, e->param[0]), min, max); 214cabdff1aSopenharmony_ci } 215cabdff1aSopenharmony_ci case e_between: { 216cabdff1aSopenharmony_ci double d = eval_expr(p, e->param[0]); 217cabdff1aSopenharmony_ci return e->value * (d >= eval_expr(p, e->param[1]) && 218cabdff1aSopenharmony_ci d <= eval_expr(p, e->param[2])); 219cabdff1aSopenharmony_ci } 220cabdff1aSopenharmony_ci case e_lerp: { 221cabdff1aSopenharmony_ci double v0 = eval_expr(p, e->param[0]); 222cabdff1aSopenharmony_ci double v1 = eval_expr(p, e->param[1]); 223cabdff1aSopenharmony_ci double f = eval_expr(p, e->param[2]); 224cabdff1aSopenharmony_ci return v0 + (v1 - v0) * f; 225cabdff1aSopenharmony_ci } 226cabdff1aSopenharmony_ci case e_print: { 227cabdff1aSopenharmony_ci double x = eval_expr(p, e->param[0]); 228cabdff1aSopenharmony_ci int level = e->param[1] ? av_clip(eval_expr(p, e->param[1]), INT_MIN, INT_MAX) : AV_LOG_INFO; 229cabdff1aSopenharmony_ci av_log(p, level, "%f\n", x); 230cabdff1aSopenharmony_ci return x; 231cabdff1aSopenharmony_ci } 232cabdff1aSopenharmony_ci case e_random:{ 233cabdff1aSopenharmony_ci int idx= av_clip(eval_expr(p, e->param[0]), 0, VARS-1); 234cabdff1aSopenharmony_ci uint64_t r= isnan(p->var[idx]) ? 0 : p->var[idx]; 235cabdff1aSopenharmony_ci r= r*1664525+1013904223; 236cabdff1aSopenharmony_ci p->var[idx]= r; 237cabdff1aSopenharmony_ci return e->value * (r * (1.0/UINT64_MAX)); 238cabdff1aSopenharmony_ci } 239cabdff1aSopenharmony_ci case e_while: { 240cabdff1aSopenharmony_ci double d = NAN; 241cabdff1aSopenharmony_ci while (eval_expr(p, e->param[0])) 242cabdff1aSopenharmony_ci d=eval_expr(p, e->param[1]); 243cabdff1aSopenharmony_ci return d; 244cabdff1aSopenharmony_ci } 245cabdff1aSopenharmony_ci case e_taylor: { 246cabdff1aSopenharmony_ci double t = 1, d = 0, v; 247cabdff1aSopenharmony_ci double x = eval_expr(p, e->param[1]); 248cabdff1aSopenharmony_ci int id = e->param[2] ? av_clip(eval_expr(p, e->param[2]), 0, VARS-1) : 0; 249cabdff1aSopenharmony_ci int i; 250cabdff1aSopenharmony_ci double var0 = p->var[id]; 251cabdff1aSopenharmony_ci for(i=0; i<1000; i++) { 252cabdff1aSopenharmony_ci double ld = d; 253cabdff1aSopenharmony_ci p->var[id] = i; 254cabdff1aSopenharmony_ci v = eval_expr(p, e->param[0]); 255cabdff1aSopenharmony_ci d += t*v; 256cabdff1aSopenharmony_ci if(ld==d && v) 257cabdff1aSopenharmony_ci break; 258cabdff1aSopenharmony_ci t *= x / (i+1); 259cabdff1aSopenharmony_ci } 260cabdff1aSopenharmony_ci p->var[id] = var0; 261cabdff1aSopenharmony_ci return d; 262cabdff1aSopenharmony_ci } 263cabdff1aSopenharmony_ci case e_root: { 264cabdff1aSopenharmony_ci int i, j; 265cabdff1aSopenharmony_ci double low = -1, high = -1, v, low_v = -DBL_MAX, high_v = DBL_MAX; 266cabdff1aSopenharmony_ci double var0 = p->var[0]; 267cabdff1aSopenharmony_ci double x_max = eval_expr(p, e->param[1]); 268cabdff1aSopenharmony_ci for(i=-1; i<1024; i++) { 269cabdff1aSopenharmony_ci if(i<255) { 270cabdff1aSopenharmony_ci p->var[0] = ff_reverse[i&255]*x_max/255; 271cabdff1aSopenharmony_ci } else { 272cabdff1aSopenharmony_ci p->var[0] = x_max*pow(0.9, i-255); 273cabdff1aSopenharmony_ci if (i&1) p->var[0] *= -1; 274cabdff1aSopenharmony_ci if (i&2) p->var[0] += low; 275cabdff1aSopenharmony_ci else p->var[0] += high; 276cabdff1aSopenharmony_ci } 277cabdff1aSopenharmony_ci v = eval_expr(p, e->param[0]); 278cabdff1aSopenharmony_ci if (v<=0 && v>low_v) { 279cabdff1aSopenharmony_ci low = p->var[0]; 280cabdff1aSopenharmony_ci low_v = v; 281cabdff1aSopenharmony_ci } 282cabdff1aSopenharmony_ci if (v>=0 && v<high_v) { 283cabdff1aSopenharmony_ci high = p->var[0]; 284cabdff1aSopenharmony_ci high_v = v; 285cabdff1aSopenharmony_ci } 286cabdff1aSopenharmony_ci if (low>=0 && high>=0){ 287cabdff1aSopenharmony_ci for (j=0; j<1000; j++) { 288cabdff1aSopenharmony_ci p->var[0] = (low+high)*0.5; 289cabdff1aSopenharmony_ci if (low == p->var[0] || high == p->var[0]) 290cabdff1aSopenharmony_ci break; 291cabdff1aSopenharmony_ci v = eval_expr(p, e->param[0]); 292cabdff1aSopenharmony_ci if (v<=0) low = p->var[0]; 293cabdff1aSopenharmony_ci if (v>=0) high= p->var[0]; 294cabdff1aSopenharmony_ci if (isnan(v)) { 295cabdff1aSopenharmony_ci low = high = v; 296cabdff1aSopenharmony_ci break; 297cabdff1aSopenharmony_ci } 298cabdff1aSopenharmony_ci } 299cabdff1aSopenharmony_ci break; 300cabdff1aSopenharmony_ci } 301cabdff1aSopenharmony_ci } 302cabdff1aSopenharmony_ci p->var[0] = var0; 303cabdff1aSopenharmony_ci return -low_v<high_v ? low : high; 304cabdff1aSopenharmony_ci } 305cabdff1aSopenharmony_ci default: { 306cabdff1aSopenharmony_ci double d = eval_expr(p, e->param[0]); 307cabdff1aSopenharmony_ci double d2 = eval_expr(p, e->param[1]); 308cabdff1aSopenharmony_ci switch (e->type) { 309cabdff1aSopenharmony_ci case e_mod: return e->value * (d - floor(d2 ? d / d2 : d * INFINITY) * d2); 310cabdff1aSopenharmony_ci case e_gcd: return e->value * av_gcd(d,d2); 311cabdff1aSopenharmony_ci case e_max: return e->value * (d > d2 ? d : d2); 312cabdff1aSopenharmony_ci case e_min: return e->value * (d < d2 ? d : d2); 313cabdff1aSopenharmony_ci case e_eq: return e->value * (d == d2 ? 1.0 : 0.0); 314cabdff1aSopenharmony_ci case e_gt: return e->value * (d > d2 ? 1.0 : 0.0); 315cabdff1aSopenharmony_ci case e_gte: return e->value * (d >= d2 ? 1.0 : 0.0); 316cabdff1aSopenharmony_ci case e_lt: return e->value * (d < d2 ? 1.0 : 0.0); 317cabdff1aSopenharmony_ci case e_lte: return e->value * (d <= d2 ? 1.0 : 0.0); 318cabdff1aSopenharmony_ci case e_pow: return e->value * pow(d, d2); 319cabdff1aSopenharmony_ci case e_mul: return e->value * (d * d2); 320cabdff1aSopenharmony_ci case e_div: return e->value * (d2 ? (d / d2) : d * INFINITY); 321cabdff1aSopenharmony_ci case e_add: return e->value * (d + d2); 322cabdff1aSopenharmony_ci case e_last:return e->value * d2; 323cabdff1aSopenharmony_ci case e_st : return e->value * (p->var[av_clip(d, 0, VARS-1)]= d2); 324cabdff1aSopenharmony_ci case e_hypot:return e->value * hypot(d, d2); 325cabdff1aSopenharmony_ci case e_atan2:return e->value * atan2(d, d2); 326cabdff1aSopenharmony_ci case e_bitand: return isnan(d) || isnan(d2) ? NAN : e->value * ((long int)d & (long int)d2); 327cabdff1aSopenharmony_ci case e_bitor: return isnan(d) || isnan(d2) ? NAN : e->value * ((long int)d | (long int)d2); 328cabdff1aSopenharmony_ci } 329cabdff1aSopenharmony_ci } 330cabdff1aSopenharmony_ci } 331cabdff1aSopenharmony_ci return NAN; 332cabdff1aSopenharmony_ci} 333cabdff1aSopenharmony_ci 334cabdff1aSopenharmony_cistatic int parse_expr(AVExpr **e, Parser *p); 335cabdff1aSopenharmony_ci 336cabdff1aSopenharmony_civoid av_expr_free(AVExpr *e) 337cabdff1aSopenharmony_ci{ 338cabdff1aSopenharmony_ci if (!e) return; 339cabdff1aSopenharmony_ci av_expr_free(e->param[0]); 340cabdff1aSopenharmony_ci av_expr_free(e->param[1]); 341cabdff1aSopenharmony_ci av_expr_free(e->param[2]); 342cabdff1aSopenharmony_ci av_freep(&e->var); 343cabdff1aSopenharmony_ci av_freep(&e); 344cabdff1aSopenharmony_ci} 345cabdff1aSopenharmony_ci 346cabdff1aSopenharmony_cistatic int parse_primary(AVExpr **e, Parser *p) 347cabdff1aSopenharmony_ci{ 348cabdff1aSopenharmony_ci AVExpr *d = av_mallocz(sizeof(AVExpr)); 349cabdff1aSopenharmony_ci char *next = p->s, *s0 = p->s; 350cabdff1aSopenharmony_ci int ret, i; 351cabdff1aSopenharmony_ci 352cabdff1aSopenharmony_ci if (!d) 353cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 354cabdff1aSopenharmony_ci 355cabdff1aSopenharmony_ci /* number */ 356cabdff1aSopenharmony_ci d->value = av_strtod(p->s, &next); 357cabdff1aSopenharmony_ci if (next != p->s) { 358cabdff1aSopenharmony_ci d->type = e_value; 359cabdff1aSopenharmony_ci p->s= next; 360cabdff1aSopenharmony_ci *e = d; 361cabdff1aSopenharmony_ci return 0; 362cabdff1aSopenharmony_ci } 363cabdff1aSopenharmony_ci d->value = 1; 364cabdff1aSopenharmony_ci 365cabdff1aSopenharmony_ci /* named constants */ 366cabdff1aSopenharmony_ci for (i=0; p->const_names && p->const_names[i]; i++) { 367cabdff1aSopenharmony_ci if (strmatch(p->s, p->const_names[i])) { 368cabdff1aSopenharmony_ci p->s+= strlen(p->const_names[i]); 369cabdff1aSopenharmony_ci d->type = e_const; 370cabdff1aSopenharmony_ci d->const_index = i; 371cabdff1aSopenharmony_ci *e = d; 372cabdff1aSopenharmony_ci return 0; 373cabdff1aSopenharmony_ci } 374cabdff1aSopenharmony_ci } 375cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(constants); i++) { 376cabdff1aSopenharmony_ci if (strmatch(p->s, constants[i].name)) { 377cabdff1aSopenharmony_ci p->s += strlen(constants[i].name); 378cabdff1aSopenharmony_ci d->type = e_value; 379cabdff1aSopenharmony_ci d->value = constants[i].value; 380cabdff1aSopenharmony_ci *e = d; 381cabdff1aSopenharmony_ci return 0; 382cabdff1aSopenharmony_ci } 383cabdff1aSopenharmony_ci } 384cabdff1aSopenharmony_ci 385cabdff1aSopenharmony_ci p->s= strchr(p->s, '('); 386cabdff1aSopenharmony_ci if (!p->s) { 387cabdff1aSopenharmony_ci av_log(p, AV_LOG_ERROR, "Undefined constant or missing '(' in '%s'\n", s0); 388cabdff1aSopenharmony_ci p->s= next; 389cabdff1aSopenharmony_ci av_expr_free(d); 390cabdff1aSopenharmony_ci return AVERROR(EINVAL); 391cabdff1aSopenharmony_ci } 392cabdff1aSopenharmony_ci p->s++; // "(" 393cabdff1aSopenharmony_ci if (*next == '(') { // special case do-nothing 394cabdff1aSopenharmony_ci av_freep(&d); 395cabdff1aSopenharmony_ci if ((ret = parse_expr(&d, p)) < 0) 396cabdff1aSopenharmony_ci return ret; 397cabdff1aSopenharmony_ci if (p->s[0] != ')') { 398cabdff1aSopenharmony_ci av_log(p, AV_LOG_ERROR, "Missing ')' in '%s'\n", s0); 399cabdff1aSopenharmony_ci av_expr_free(d); 400cabdff1aSopenharmony_ci return AVERROR(EINVAL); 401cabdff1aSopenharmony_ci } 402cabdff1aSopenharmony_ci p->s++; // ")" 403cabdff1aSopenharmony_ci *e = d; 404cabdff1aSopenharmony_ci return 0; 405cabdff1aSopenharmony_ci } 406cabdff1aSopenharmony_ci if ((ret = parse_expr(&(d->param[0]), p)) < 0) { 407cabdff1aSopenharmony_ci av_expr_free(d); 408cabdff1aSopenharmony_ci return ret; 409cabdff1aSopenharmony_ci } 410cabdff1aSopenharmony_ci if (p->s[0]== ',') { 411cabdff1aSopenharmony_ci p->s++; // "," 412cabdff1aSopenharmony_ci parse_expr(&d->param[1], p); 413cabdff1aSopenharmony_ci } 414cabdff1aSopenharmony_ci if (p->s[0]== ',') { 415cabdff1aSopenharmony_ci p->s++; // "," 416cabdff1aSopenharmony_ci parse_expr(&d->param[2], p); 417cabdff1aSopenharmony_ci } 418cabdff1aSopenharmony_ci if (p->s[0] != ')') { 419cabdff1aSopenharmony_ci av_log(p, AV_LOG_ERROR, "Missing ')' or too many args in '%s'\n", s0); 420cabdff1aSopenharmony_ci av_expr_free(d); 421cabdff1aSopenharmony_ci return AVERROR(EINVAL); 422cabdff1aSopenharmony_ci } 423cabdff1aSopenharmony_ci p->s++; // ")" 424cabdff1aSopenharmony_ci 425cabdff1aSopenharmony_ci d->type = e_func0; 426cabdff1aSopenharmony_ci if (strmatch(next, "sinh" )) d->a.func0 = sinh; 427cabdff1aSopenharmony_ci else if (strmatch(next, "cosh" )) d->a.func0 = cosh; 428cabdff1aSopenharmony_ci else if (strmatch(next, "tanh" )) d->a.func0 = tanh; 429cabdff1aSopenharmony_ci else if (strmatch(next, "sin" )) d->a.func0 = sin; 430cabdff1aSopenharmony_ci else if (strmatch(next, "cos" )) d->a.func0 = cos; 431cabdff1aSopenharmony_ci else if (strmatch(next, "tan" )) d->a.func0 = tan; 432cabdff1aSopenharmony_ci else if (strmatch(next, "atan" )) d->a.func0 = atan; 433cabdff1aSopenharmony_ci else if (strmatch(next, "asin" )) d->a.func0 = asin; 434cabdff1aSopenharmony_ci else if (strmatch(next, "acos" )) d->a.func0 = acos; 435cabdff1aSopenharmony_ci else if (strmatch(next, "exp" )) d->a.func0 = exp; 436cabdff1aSopenharmony_ci else if (strmatch(next, "log" )) d->a.func0 = log; 437cabdff1aSopenharmony_ci else if (strmatch(next, "abs" )) d->a.func0 = fabs; 438cabdff1aSopenharmony_ci else if (strmatch(next, "time" )) d->a.func0 = etime; 439cabdff1aSopenharmony_ci else if (strmatch(next, "squish")) d->type = e_squish; 440cabdff1aSopenharmony_ci else if (strmatch(next, "gauss" )) d->type = e_gauss; 441cabdff1aSopenharmony_ci else if (strmatch(next, "mod" )) d->type = e_mod; 442cabdff1aSopenharmony_ci else if (strmatch(next, "max" )) d->type = e_max; 443cabdff1aSopenharmony_ci else if (strmatch(next, "min" )) d->type = e_min; 444cabdff1aSopenharmony_ci else if (strmatch(next, "eq" )) d->type = e_eq; 445cabdff1aSopenharmony_ci else if (strmatch(next, "gte" )) d->type = e_gte; 446cabdff1aSopenharmony_ci else if (strmatch(next, "gt" )) d->type = e_gt; 447cabdff1aSopenharmony_ci else if (strmatch(next, "lte" )) d->type = e_lte; 448cabdff1aSopenharmony_ci else if (strmatch(next, "lt" )) d->type = e_lt; 449cabdff1aSopenharmony_ci else if (strmatch(next, "ld" )) d->type = e_ld; 450cabdff1aSopenharmony_ci else if (strmatch(next, "isnan" )) d->type = e_isnan; 451cabdff1aSopenharmony_ci else if (strmatch(next, "isinf" )) d->type = e_isinf; 452cabdff1aSopenharmony_ci else if (strmatch(next, "st" )) d->type = e_st; 453cabdff1aSopenharmony_ci else if (strmatch(next, "while" )) d->type = e_while; 454cabdff1aSopenharmony_ci else if (strmatch(next, "taylor")) d->type = e_taylor; 455cabdff1aSopenharmony_ci else if (strmatch(next, "root" )) d->type = e_root; 456cabdff1aSopenharmony_ci else if (strmatch(next, "floor" )) d->type = e_floor; 457cabdff1aSopenharmony_ci else if (strmatch(next, "ceil" )) d->type = e_ceil; 458cabdff1aSopenharmony_ci else if (strmatch(next, "trunc" )) d->type = e_trunc; 459cabdff1aSopenharmony_ci else if (strmatch(next, "round" )) d->type = e_round; 460cabdff1aSopenharmony_ci else if (strmatch(next, "sqrt" )) d->type = e_sqrt; 461cabdff1aSopenharmony_ci else if (strmatch(next, "not" )) d->type = e_not; 462cabdff1aSopenharmony_ci else if (strmatch(next, "pow" )) d->type = e_pow; 463cabdff1aSopenharmony_ci else if (strmatch(next, "print" )) d->type = e_print; 464cabdff1aSopenharmony_ci else if (strmatch(next, "random")) d->type = e_random; 465cabdff1aSopenharmony_ci else if (strmatch(next, "hypot" )) d->type = e_hypot; 466cabdff1aSopenharmony_ci else if (strmatch(next, "gcd" )) d->type = e_gcd; 467cabdff1aSopenharmony_ci else if (strmatch(next, "if" )) d->type = e_if; 468cabdff1aSopenharmony_ci else if (strmatch(next, "ifnot" )) d->type = e_ifnot; 469cabdff1aSopenharmony_ci else if (strmatch(next, "bitand")) d->type = e_bitand; 470cabdff1aSopenharmony_ci else if (strmatch(next, "bitor" )) d->type = e_bitor; 471cabdff1aSopenharmony_ci else if (strmatch(next, "between"))d->type = e_between; 472cabdff1aSopenharmony_ci else if (strmatch(next, "clip" )) d->type = e_clip; 473cabdff1aSopenharmony_ci else if (strmatch(next, "atan2" )) d->type = e_atan2; 474cabdff1aSopenharmony_ci else if (strmatch(next, "lerp" )) d->type = e_lerp; 475cabdff1aSopenharmony_ci else if (strmatch(next, "sgn" )) d->type = e_sgn; 476cabdff1aSopenharmony_ci else { 477cabdff1aSopenharmony_ci for (i=0; p->func1_names && p->func1_names[i]; i++) { 478cabdff1aSopenharmony_ci if (strmatch(next, p->func1_names[i])) { 479cabdff1aSopenharmony_ci d->a.func1 = p->funcs1[i]; 480cabdff1aSopenharmony_ci d->type = e_func1; 481cabdff1aSopenharmony_ci d->const_index = i; 482cabdff1aSopenharmony_ci *e = d; 483cabdff1aSopenharmony_ci return 0; 484cabdff1aSopenharmony_ci } 485cabdff1aSopenharmony_ci } 486cabdff1aSopenharmony_ci 487cabdff1aSopenharmony_ci for (i=0; p->func2_names && p->func2_names[i]; i++) { 488cabdff1aSopenharmony_ci if (strmatch(next, p->func2_names[i])) { 489cabdff1aSopenharmony_ci d->a.func2 = p->funcs2[i]; 490cabdff1aSopenharmony_ci d->type = e_func2; 491cabdff1aSopenharmony_ci d->const_index = i; 492cabdff1aSopenharmony_ci *e = d; 493cabdff1aSopenharmony_ci return 0; 494cabdff1aSopenharmony_ci } 495cabdff1aSopenharmony_ci } 496cabdff1aSopenharmony_ci 497cabdff1aSopenharmony_ci av_log(p, AV_LOG_ERROR, "Unknown function in '%s'\n", s0); 498cabdff1aSopenharmony_ci av_expr_free(d); 499cabdff1aSopenharmony_ci return AVERROR(EINVAL); 500cabdff1aSopenharmony_ci } 501cabdff1aSopenharmony_ci 502cabdff1aSopenharmony_ci *e = d; 503cabdff1aSopenharmony_ci return 0; 504cabdff1aSopenharmony_ci} 505cabdff1aSopenharmony_ci 506cabdff1aSopenharmony_cistatic AVExpr *make_eval_expr(int type, int value, AVExpr *p0, AVExpr *p1) 507cabdff1aSopenharmony_ci{ 508cabdff1aSopenharmony_ci AVExpr *e = av_mallocz(sizeof(AVExpr)); 509cabdff1aSopenharmony_ci if (!e) 510cabdff1aSopenharmony_ci return NULL; 511cabdff1aSopenharmony_ci e->type =type ; 512cabdff1aSopenharmony_ci e->value =value ; 513cabdff1aSopenharmony_ci e->param[0] =p0 ; 514cabdff1aSopenharmony_ci e->param[1] =p1 ; 515cabdff1aSopenharmony_ci return e; 516cabdff1aSopenharmony_ci} 517cabdff1aSopenharmony_ci 518cabdff1aSopenharmony_cistatic int parse_pow(AVExpr **e, Parser *p, int *sign) 519cabdff1aSopenharmony_ci{ 520cabdff1aSopenharmony_ci *sign= (*p->s == '+') - (*p->s == '-'); 521cabdff1aSopenharmony_ci p->s += *sign&1; 522cabdff1aSopenharmony_ci return parse_primary(e, p); 523cabdff1aSopenharmony_ci} 524cabdff1aSopenharmony_ci 525cabdff1aSopenharmony_cistatic int parse_dB(AVExpr **e, Parser *p, int *sign) 526cabdff1aSopenharmony_ci{ 527cabdff1aSopenharmony_ci /* do not filter out the negative sign when parsing a dB value. 528cabdff1aSopenharmony_ci for example, -3dB is not the same as -(3dB) */ 529cabdff1aSopenharmony_ci if (*p->s == '-') { 530cabdff1aSopenharmony_ci char *next; 531cabdff1aSopenharmony_ci double av_unused ignored = strtod(p->s, &next); 532cabdff1aSopenharmony_ci if (next != p->s && next[0] == 'd' && next[1] == 'B') { 533cabdff1aSopenharmony_ci *sign = 0; 534cabdff1aSopenharmony_ci return parse_primary(e, p); 535cabdff1aSopenharmony_ci } 536cabdff1aSopenharmony_ci } 537cabdff1aSopenharmony_ci return parse_pow(e, p, sign); 538cabdff1aSopenharmony_ci} 539cabdff1aSopenharmony_ci 540cabdff1aSopenharmony_cistatic int parse_factor(AVExpr **e, Parser *p) 541cabdff1aSopenharmony_ci{ 542cabdff1aSopenharmony_ci int sign, sign2, ret; 543cabdff1aSopenharmony_ci AVExpr *e0, *e1, *e2; 544cabdff1aSopenharmony_ci if ((ret = parse_dB(&e0, p, &sign)) < 0) 545cabdff1aSopenharmony_ci return ret; 546cabdff1aSopenharmony_ci while(p->s[0]=='^'){ 547cabdff1aSopenharmony_ci e1 = e0; 548cabdff1aSopenharmony_ci p->s++; 549cabdff1aSopenharmony_ci if ((ret = parse_dB(&e2, p, &sign2)) < 0) { 550cabdff1aSopenharmony_ci av_expr_free(e1); 551cabdff1aSopenharmony_ci return ret; 552cabdff1aSopenharmony_ci } 553cabdff1aSopenharmony_ci e0 = make_eval_expr(e_pow, 1, e1, e2); 554cabdff1aSopenharmony_ci if (!e0) { 555cabdff1aSopenharmony_ci av_expr_free(e1); 556cabdff1aSopenharmony_ci av_expr_free(e2); 557cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 558cabdff1aSopenharmony_ci } 559cabdff1aSopenharmony_ci if (e0->param[1]) e0->param[1]->value *= (sign2|1); 560cabdff1aSopenharmony_ci } 561cabdff1aSopenharmony_ci if (e0) e0->value *= (sign|1); 562cabdff1aSopenharmony_ci 563cabdff1aSopenharmony_ci *e = e0; 564cabdff1aSopenharmony_ci return 0; 565cabdff1aSopenharmony_ci} 566cabdff1aSopenharmony_ci 567cabdff1aSopenharmony_cistatic int parse_term(AVExpr **e, Parser *p) 568cabdff1aSopenharmony_ci{ 569cabdff1aSopenharmony_ci int ret; 570cabdff1aSopenharmony_ci AVExpr *e0, *e1, *e2; 571cabdff1aSopenharmony_ci if ((ret = parse_factor(&e0, p)) < 0) 572cabdff1aSopenharmony_ci return ret; 573cabdff1aSopenharmony_ci while (p->s[0]=='*' || p->s[0]=='/') { 574cabdff1aSopenharmony_ci int c= *p->s++; 575cabdff1aSopenharmony_ci e1 = e0; 576cabdff1aSopenharmony_ci if ((ret = parse_factor(&e2, p)) < 0) { 577cabdff1aSopenharmony_ci av_expr_free(e1); 578cabdff1aSopenharmony_ci return ret; 579cabdff1aSopenharmony_ci } 580cabdff1aSopenharmony_ci e0 = make_eval_expr(c == '*' ? e_mul : e_div, 1, e1, e2); 581cabdff1aSopenharmony_ci if (!e0) { 582cabdff1aSopenharmony_ci av_expr_free(e1); 583cabdff1aSopenharmony_ci av_expr_free(e2); 584cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 585cabdff1aSopenharmony_ci } 586cabdff1aSopenharmony_ci } 587cabdff1aSopenharmony_ci *e = e0; 588cabdff1aSopenharmony_ci return 0; 589cabdff1aSopenharmony_ci} 590cabdff1aSopenharmony_ci 591cabdff1aSopenharmony_cistatic int parse_subexpr(AVExpr **e, Parser *p) 592cabdff1aSopenharmony_ci{ 593cabdff1aSopenharmony_ci int ret; 594cabdff1aSopenharmony_ci AVExpr *e0, *e1, *e2; 595cabdff1aSopenharmony_ci if ((ret = parse_term(&e0, p)) < 0) 596cabdff1aSopenharmony_ci return ret; 597cabdff1aSopenharmony_ci while (*p->s == '+' || *p->s == '-') { 598cabdff1aSopenharmony_ci e1 = e0; 599cabdff1aSopenharmony_ci if ((ret = parse_term(&e2, p)) < 0) { 600cabdff1aSopenharmony_ci av_expr_free(e1); 601cabdff1aSopenharmony_ci return ret; 602cabdff1aSopenharmony_ci } 603cabdff1aSopenharmony_ci e0 = make_eval_expr(e_add, 1, e1, e2); 604cabdff1aSopenharmony_ci if (!e0) { 605cabdff1aSopenharmony_ci av_expr_free(e1); 606cabdff1aSopenharmony_ci av_expr_free(e2); 607cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 608cabdff1aSopenharmony_ci } 609cabdff1aSopenharmony_ci }; 610cabdff1aSopenharmony_ci 611cabdff1aSopenharmony_ci *e = e0; 612cabdff1aSopenharmony_ci return 0; 613cabdff1aSopenharmony_ci} 614cabdff1aSopenharmony_ci 615cabdff1aSopenharmony_cistatic int parse_expr(AVExpr **e, Parser *p) 616cabdff1aSopenharmony_ci{ 617cabdff1aSopenharmony_ci int ret; 618cabdff1aSopenharmony_ci AVExpr *e0, *e1, *e2; 619cabdff1aSopenharmony_ci if (p->stack_index <= 0) //protect against stack overflows 620cabdff1aSopenharmony_ci return AVERROR(EINVAL); 621cabdff1aSopenharmony_ci p->stack_index--; 622cabdff1aSopenharmony_ci 623cabdff1aSopenharmony_ci if ((ret = parse_subexpr(&e0, p)) < 0) 624cabdff1aSopenharmony_ci return ret; 625cabdff1aSopenharmony_ci while (*p->s == ';') { 626cabdff1aSopenharmony_ci p->s++; 627cabdff1aSopenharmony_ci e1 = e0; 628cabdff1aSopenharmony_ci if ((ret = parse_subexpr(&e2, p)) < 0) { 629cabdff1aSopenharmony_ci av_expr_free(e1); 630cabdff1aSopenharmony_ci return ret; 631cabdff1aSopenharmony_ci } 632cabdff1aSopenharmony_ci e0 = make_eval_expr(e_last, 1, e1, e2); 633cabdff1aSopenharmony_ci if (!e0) { 634cabdff1aSopenharmony_ci av_expr_free(e1); 635cabdff1aSopenharmony_ci av_expr_free(e2); 636cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 637cabdff1aSopenharmony_ci } 638cabdff1aSopenharmony_ci }; 639cabdff1aSopenharmony_ci 640cabdff1aSopenharmony_ci p->stack_index++; 641cabdff1aSopenharmony_ci *e = e0; 642cabdff1aSopenharmony_ci return 0; 643cabdff1aSopenharmony_ci} 644cabdff1aSopenharmony_ci 645cabdff1aSopenharmony_cistatic int verify_expr(AVExpr *e) 646cabdff1aSopenharmony_ci{ 647cabdff1aSopenharmony_ci if (!e) return 0; 648cabdff1aSopenharmony_ci switch (e->type) { 649cabdff1aSopenharmony_ci case e_value: 650cabdff1aSopenharmony_ci case e_const: return 1; 651cabdff1aSopenharmony_ci case e_func0: 652cabdff1aSopenharmony_ci case e_func1: 653cabdff1aSopenharmony_ci case e_squish: 654cabdff1aSopenharmony_ci case e_ld: 655cabdff1aSopenharmony_ci case e_gauss: 656cabdff1aSopenharmony_ci case e_isnan: 657cabdff1aSopenharmony_ci case e_isinf: 658cabdff1aSopenharmony_ci case e_floor: 659cabdff1aSopenharmony_ci case e_ceil: 660cabdff1aSopenharmony_ci case e_trunc: 661cabdff1aSopenharmony_ci case e_round: 662cabdff1aSopenharmony_ci case e_sqrt: 663cabdff1aSopenharmony_ci case e_not: 664cabdff1aSopenharmony_ci case e_random: 665cabdff1aSopenharmony_ci case e_sgn: 666cabdff1aSopenharmony_ci return verify_expr(e->param[0]) && !e->param[1]; 667cabdff1aSopenharmony_ci case e_print: 668cabdff1aSopenharmony_ci return verify_expr(e->param[0]) 669cabdff1aSopenharmony_ci && (!e->param[1] || verify_expr(e->param[1])); 670cabdff1aSopenharmony_ci case e_if: 671cabdff1aSopenharmony_ci case e_ifnot: 672cabdff1aSopenharmony_ci case e_taylor: 673cabdff1aSopenharmony_ci return verify_expr(e->param[0]) && verify_expr(e->param[1]) 674cabdff1aSopenharmony_ci && (!e->param[2] || verify_expr(e->param[2])); 675cabdff1aSopenharmony_ci case e_between: 676cabdff1aSopenharmony_ci case e_clip: 677cabdff1aSopenharmony_ci case e_lerp: 678cabdff1aSopenharmony_ci return verify_expr(e->param[0]) && 679cabdff1aSopenharmony_ci verify_expr(e->param[1]) && 680cabdff1aSopenharmony_ci verify_expr(e->param[2]); 681cabdff1aSopenharmony_ci default: return verify_expr(e->param[0]) && verify_expr(e->param[1]) && !e->param[2]; 682cabdff1aSopenharmony_ci } 683cabdff1aSopenharmony_ci} 684cabdff1aSopenharmony_ci 685cabdff1aSopenharmony_ciint av_expr_parse(AVExpr **expr, const char *s, 686cabdff1aSopenharmony_ci const char * const *const_names, 687cabdff1aSopenharmony_ci const char * const *func1_names, double (* const *funcs1)(void *, double), 688cabdff1aSopenharmony_ci const char * const *func2_names, double (* const *funcs2)(void *, double, double), 689cabdff1aSopenharmony_ci int log_offset, void *log_ctx) 690cabdff1aSopenharmony_ci{ 691cabdff1aSopenharmony_ci Parser p = { 0 }; 692cabdff1aSopenharmony_ci AVExpr *e = NULL; 693cabdff1aSopenharmony_ci char *w = av_malloc(strlen(s) + 1); 694cabdff1aSopenharmony_ci char *wp = w; 695cabdff1aSopenharmony_ci const char *s0 = s; 696cabdff1aSopenharmony_ci int ret = 0; 697cabdff1aSopenharmony_ci 698cabdff1aSopenharmony_ci if (!w) 699cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 700cabdff1aSopenharmony_ci 701cabdff1aSopenharmony_ci while (*s) 702cabdff1aSopenharmony_ci if (!av_isspace(*s++)) *wp++ = s[-1]; 703cabdff1aSopenharmony_ci *wp++ = 0; 704cabdff1aSopenharmony_ci 705cabdff1aSopenharmony_ci p.class = &eval_class; 706cabdff1aSopenharmony_ci p.stack_index=100; 707cabdff1aSopenharmony_ci p.s= w; 708cabdff1aSopenharmony_ci p.const_names = const_names; 709cabdff1aSopenharmony_ci p.funcs1 = funcs1; 710cabdff1aSopenharmony_ci p.func1_names = func1_names; 711cabdff1aSopenharmony_ci p.funcs2 = funcs2; 712cabdff1aSopenharmony_ci p.func2_names = func2_names; 713cabdff1aSopenharmony_ci p.log_offset = log_offset; 714cabdff1aSopenharmony_ci p.log_ctx = log_ctx; 715cabdff1aSopenharmony_ci 716cabdff1aSopenharmony_ci if ((ret = parse_expr(&e, &p)) < 0) 717cabdff1aSopenharmony_ci goto end; 718cabdff1aSopenharmony_ci if (*p.s) { 719cabdff1aSopenharmony_ci av_log(&p, AV_LOG_ERROR, "Invalid chars '%s' at the end of expression '%s'\n", p.s, s0); 720cabdff1aSopenharmony_ci ret = AVERROR(EINVAL); 721cabdff1aSopenharmony_ci goto end; 722cabdff1aSopenharmony_ci } 723cabdff1aSopenharmony_ci if (!verify_expr(e)) { 724cabdff1aSopenharmony_ci ret = AVERROR(EINVAL); 725cabdff1aSopenharmony_ci goto end; 726cabdff1aSopenharmony_ci } 727cabdff1aSopenharmony_ci e->var= av_mallocz(sizeof(double) *VARS); 728cabdff1aSopenharmony_ci if (!e->var) { 729cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 730cabdff1aSopenharmony_ci goto end; 731cabdff1aSopenharmony_ci } 732cabdff1aSopenharmony_ci *expr = e; 733cabdff1aSopenharmony_ci e = NULL; 734cabdff1aSopenharmony_ciend: 735cabdff1aSopenharmony_ci av_expr_free(e); 736cabdff1aSopenharmony_ci av_free(w); 737cabdff1aSopenharmony_ci return ret; 738cabdff1aSopenharmony_ci} 739cabdff1aSopenharmony_ci 740cabdff1aSopenharmony_cistatic int expr_count(AVExpr *e, unsigned *counter, int size, int type) 741cabdff1aSopenharmony_ci{ 742cabdff1aSopenharmony_ci int i; 743cabdff1aSopenharmony_ci 744cabdff1aSopenharmony_ci if (!e || !counter || !size) 745cabdff1aSopenharmony_ci return AVERROR(EINVAL); 746cabdff1aSopenharmony_ci 747cabdff1aSopenharmony_ci for (i = 0; e->type != type && i < 3 && e->param[i]; i++) 748cabdff1aSopenharmony_ci expr_count(e->param[i], counter, size, type); 749cabdff1aSopenharmony_ci 750cabdff1aSopenharmony_ci if (e->type == type && e->const_index < size) 751cabdff1aSopenharmony_ci counter[e->const_index]++; 752cabdff1aSopenharmony_ci 753cabdff1aSopenharmony_ci return 0; 754cabdff1aSopenharmony_ci} 755cabdff1aSopenharmony_ci 756cabdff1aSopenharmony_ciint av_expr_count_vars(AVExpr *e, unsigned *counter, int size) 757cabdff1aSopenharmony_ci{ 758cabdff1aSopenharmony_ci return expr_count(e, counter, size, e_const); 759cabdff1aSopenharmony_ci} 760cabdff1aSopenharmony_ci 761cabdff1aSopenharmony_ciint av_expr_count_func(AVExpr *e, unsigned *counter, int size, int arg) 762cabdff1aSopenharmony_ci{ 763cabdff1aSopenharmony_ci return expr_count(e, counter, size, ((int[]){e_const, e_func1, e_func2})[arg]); 764cabdff1aSopenharmony_ci} 765cabdff1aSopenharmony_ci 766cabdff1aSopenharmony_cidouble av_expr_eval(AVExpr *e, const double *const_values, void *opaque) 767cabdff1aSopenharmony_ci{ 768cabdff1aSopenharmony_ci Parser p = { 0 }; 769cabdff1aSopenharmony_ci p.var= e->var; 770cabdff1aSopenharmony_ci 771cabdff1aSopenharmony_ci p.const_values = const_values; 772cabdff1aSopenharmony_ci p.opaque = opaque; 773cabdff1aSopenharmony_ci return eval_expr(&p, e); 774cabdff1aSopenharmony_ci} 775cabdff1aSopenharmony_ci 776cabdff1aSopenharmony_ciint av_expr_parse_and_eval(double *d, const char *s, 777cabdff1aSopenharmony_ci const char * const *const_names, const double *const_values, 778cabdff1aSopenharmony_ci const char * const *func1_names, double (* const *funcs1)(void *, double), 779cabdff1aSopenharmony_ci const char * const *func2_names, double (* const *funcs2)(void *, double, double), 780cabdff1aSopenharmony_ci void *opaque, int log_offset, void *log_ctx) 781cabdff1aSopenharmony_ci{ 782cabdff1aSopenharmony_ci AVExpr *e = NULL; 783cabdff1aSopenharmony_ci int ret = av_expr_parse(&e, s, const_names, func1_names, funcs1, func2_names, funcs2, log_offset, log_ctx); 784cabdff1aSopenharmony_ci 785cabdff1aSopenharmony_ci if (ret < 0) { 786cabdff1aSopenharmony_ci *d = NAN; 787cabdff1aSopenharmony_ci return ret; 788cabdff1aSopenharmony_ci } 789cabdff1aSopenharmony_ci *d = av_expr_eval(e, const_values, opaque); 790cabdff1aSopenharmony_ci av_expr_free(e); 791cabdff1aSopenharmony_ci return isnan(*d) ? AVERROR(EINVAL) : 0; 792cabdff1aSopenharmony_ci} 793