4
4
* Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
6
* This library is free software; you can redistribute it and/or
6
* This file is part of FFmpeg.
8
* FFmpeg is free software; you can redistribute it and/or
7
9
* modify it under the terms of the GNU Lesser General Public
8
10
* License as published by the Free Software Foundation; either
9
* version 2 of the License, or (at your option) any later version.
11
* version 2.1 of the License, or (at your option) any later version.
11
* This library is distributed in the hope that it will be useful,
13
* FFmpeg is distributed in the hope that it will be useful,
12
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
16
* Lesser General Public License for more details.
16
18
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
19
* License along with FFmpeg; if not, write to the Free Software
18
20
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
52
54
double (**func2)(void *, double a, double b); // NULL terminated
53
55
char **func2_name; // NULL terminated
57
60
static double evalExpression(Parser *p);
62
static int8_t si_prefixes['z' - 'E' + 1]={
85
/** strtod() function extended with 'k', 'M', 'G', 'ki', 'Mi', 'Gi' and 'B'
86
* postfixes. This allows using f.e. kB, MiB, G and B as a postfix. This
87
* function assumes that the unit of numbers is bits not bytes.
89
static double av_strtod(const char *name, char **tail) {
92
d = strtod(name, &next);
93
/* if parsing succeeded, check for and interpret postfixes */
96
if(*next >= 'E' && *next <= 'z'){
97
int e= si_prefixes[*next - 'E'];
114
/* if requested, fill in tail with the position after the last parsed
59
121
static int strmatch(const char *s, const char *prefix){
61
123
for(i=0; prefix[i]; i++){
107
170
else if( strmatch(next, "sin" ) ) d= sin(d);
108
171
else if( strmatch(next, "cos" ) ) d= cos(d);
109
172
else if( strmatch(next, "tan" ) ) d= tan(d);
173
else if( strmatch(next, "atan" ) ) d= atan(d);
174
else if( strmatch(next, "asin" ) ) d= asin(d);
175
else if( strmatch(next, "acos" ) ) d= acos(d);
110
176
else if( strmatch(next, "exp" ) ) d= exp(d);
111
177
else if( strmatch(next, "log" ) ) d= log(d);
112
178
else if( strmatch(next, "squish") ) d= 1/(1+exp(4*d));
113
179
else if( strmatch(next, "gauss" ) ) d= exp(-d*d/2)/sqrt(2*M_PI);
114
180
else if( strmatch(next, "abs" ) ) d= fabs(d);
115
else if( strmatch(next, "max" ) ) d= d > d2 ? d : d2;
116
else if( strmatch(next, "min" ) ) d= d < d2 ? d : d2;
117
else if( strmatch(next, "gt" ) ) d= d > d2 ? 1.0 : 0.0;
118
else if( strmatch(next, "gte" ) ) d= d >= d2 ? 1.0 : 0.0;
119
else if( strmatch(next, "lt" ) ) d= d > d2 ? 0.0 : 1.0;
120
else if( strmatch(next, "lte" ) ) d= d >= d2 ? 0.0 : 1.0;
181
else if( strmatch(next, "mod" ) ) d-= floor(d/d2)*d2;
182
else if( strmatch(next, "max" ) ) d= d > d2 ? d : d2;
183
else if( strmatch(next, "min" ) ) d= d < d2 ? d : d2;
184
else if( strmatch(next, "gt" ) ) d= d > d2 ? 1.0 : 0.0;
185
else if( strmatch(next, "gte" ) ) d= d >= d2 ? 1.0 : 0.0;
186
else if( strmatch(next, "lt" ) ) d= d > d2 ? 0.0 : 1.0;
187
else if( strmatch(next, "lte" ) ) d= d >= d2 ? 0.0 : 1.0;
121
188
else if( strmatch(next, "eq" ) ) d= d == d2 ? 1.0 : 0.0;
122
189
else if( strmatch(next, "(" ) ) d= d;
123
190
// else if( strmatch(next, "l1" ) ) d= 1 + d2*(d - 1);
138
av_log(NULL, AV_LOG_ERROR, "Parser: unknown function in \"%s\"\n", next);
205
*p->error = "unknown function";
145
static double evalPow(Parser *p){
146
int sign= (*p->s == '+') - (*p->s == '-');
148
return (sign|1) * evalPrimary(p);
212
static double evalPow(Parser *p, int *sign){
213
*sign= (*p->s == '+') - (*p->s == '-');
215
return evalPrimary(p);
151
218
static double evalFactor(Parser *p){
152
double ret= evalPow(p);
221
ret= evalPow(p, &sign);
153
222
while(p->s[0]=='^'){
155
ret= pow(ret, evalPow(p));
224
e= evalPow(p, &sign2);
225
ret= pow(ret, (sign2|1) * e);
227
return (sign|1) * ret;
160
230
static double evalTerm(Parser *p){
185
double ff_eval(char *s, double *const_value, const char **const_name,
255
double ff_eval2(char *s, double *const_value, const char **const_name,
186
256
double (**func1)(void *, double), const char **func1_name,
187
257
double (**func2)(void *, double, double), char **func2_name,
258
void *opaque, char **error){
191
261
p.stack_index=100;
198
268
p.func2_name = func2_name;
199
269
p.opaque = opaque;
201
272
return evalExpression(&p);
275
#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
276
attribute_deprecated double ff_eval(char *s, double *const_value, const char **const_name,
277
double (**func1)(void *, double), const char **func1_name,
278
double (**func2)(void *, double, double), char **func2_name,
282
ret = ff_eval2(s, const_value, const_name, func1, func1_name, func2, func2_name, opaque, &error);
284
av_log(NULL, AV_LOG_ERROR, "Error evaluating \"%s\": %s\n", s, error);
206
291
static double const_values[]={
218
303
printf("%f == 12.7\n", ff_eval("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_values, const_names, NULL, NULL, NULL, NULL, NULL));
304
printf("%f == 0.931322575\n", ff_eval("80G/80Gi", const_values, const_names, NULL, NULL, NULL, NULL, NULL));
220
306
for(i=0; i<1050; i++){