comparison eval.c @ 11803:f443ef5ec4e2 libavcodec

Cosmetics: consistently apply K&R style. Make me and Diego happy.
author stefano
date Tue, 01 Jun 2010 08:07:15 +0000
parents 5880d90f2b99
children 3dc6ee95d63a
comparison
equal deleted inserted replaced
11802:5880d90f2b99 11803:f443ef5ec4e2
27 */ 27 */
28 28
29 #include "libavutil/avutil.h" 29 #include "libavutil/avutil.h"
30 #include "eval.h" 30 #include "eval.h"
31 31
32 typedef struct Parser{ 32 typedef struct Parser {
33 const AVClass *class; 33 const AVClass *class;
34 int stack_index; 34 int stack_index;
35 char *s; 35 char *s;
36 const double *const_values; 36 const double *const_values;
37 const char * const *const_names; // NULL terminated 37 const char * const *const_names; // NULL terminated
46 double var[VARS]; 46 double var[VARS];
47 } Parser; 47 } Parser;
48 48
49 static const AVClass class = { "Eval", av_default_item_name, NULL, LIBAVUTIL_VERSION_INT, offsetof(Parser,log_offset), offsetof(Parser,log_ctx) }; 49 static const AVClass class = { "Eval", av_default_item_name, NULL, LIBAVUTIL_VERSION_INT, offsetof(Parser,log_offset), offsetof(Parser,log_ctx) };
50 50
51 static const int8_t si_prefixes['z' - 'E' + 1]={ 51 static const int8_t si_prefixes['z' - 'E' + 1] = {
52 ['y'-'E']= -24, 52 ['y'-'E']= -24,
53 ['z'-'E']= -21, 53 ['z'-'E']= -21,
54 ['a'-'E']= -18, 54 ['a'-'E']= -18,
55 ['f'-'E']= -15, 55 ['f'-'E']= -15,
56 ['p'-'E']= -12, 56 ['p'-'E']= -12,
69 ['E'-'E']= 18, 69 ['E'-'E']= 18,
70 ['Z'-'E']= 21, 70 ['Z'-'E']= 21,
71 ['Y'-'E']= 24, 71 ['Y'-'E']= 24,
72 }; 72 };
73 73
74 double av_strtod(const char *numstr, char **tail) { 74 double av_strtod(const char *numstr, char **tail)
75 {
75 double d; 76 double d;
76 char *next; 77 char *next;
77 d = strtod(numstr, &next); 78 d = strtod(numstr, &next);
78 /* if parsing succeeded, check for and interpret postfixes */ 79 /* if parsing succeeded, check for and interpret postfixes */
79 if (next!=numstr) { 80 if (next!=numstr) {
80 81 if (*next >= 'E' && *next <= 'z') {
81 if(*next >= 'E' && *next <= 'z'){
82 int e= si_prefixes[*next - 'E']; 82 int e= si_prefixes[*next - 'E'];
83 if(e){ 83 if (e) {
84 if(next[1] == 'i'){ 84 if (next[1] == 'i') {
85 d*= pow( 2, e/0.3); 85 d*= pow( 2, e/0.3);
86 next+=2; 86 next+=2;
87 }else{ 87 } else {
88 d*= pow(10, e); 88 d*= pow(10, e);
89 next++; 89 next++;
90 } 90 }
91 } 91 }
92 } 92 }
93 93
94 if(*next=='B') { 94 if (*next=='B') {
95 d*=8; 95 d*=8;
96 next++; 96 next++;
97 } 97 }
98 } 98 }
99 /* if requested, fill in tail with the position after the last parsed 99 /* if requested, fill in tail with the position after the last parsed
101 if (tail) 101 if (tail)
102 *tail = next; 102 *tail = next;
103 return d; 103 return d;
104 } 104 }
105 105
106 static int strmatch(const char *s, const char *prefix){ 106 static int strmatch(const char *s, const char *prefix)
107 {
107 int i; 108 int i;
108 for(i=0; prefix[i]; i++){ 109 for (i=0; prefix[i]; i++) {
109 if(prefix[i] != s[i]) return 0; 110 if (prefix[i] != s[i]) return 0;
110 } 111 }
111 return 1; 112 return 1;
112 } 113 }
113 114
114 struct AVExpr { 115 struct AVExpr {
127 double (*func2)(void *, double, double); 128 double (*func2)(void *, double, double);
128 } a; 129 } a;
129 struct AVExpr *param[2]; 130 struct AVExpr *param[2];
130 }; 131 };
131 132
132 static double eval_expr(Parser * p, AVExpr * e) { 133 static double eval_expr(Parser *p, AVExpr *e)
134 {
133 switch (e->type) { 135 switch (e->type) {
134 case e_value: return e->value; 136 case e_value: return e->value;
135 case e_const: return e->value * p->const_values[e->a.const_index]; 137 case e_const: return e->value * p->const_values[e->a.const_index];
136 case e_func0: return e->value * e->a.func0(eval_expr(p, e->param[0])); 138 case e_func0: return e->value * e->a.func0(eval_expr(p, e->param[0]));
137 case e_func1: return e->value * e->a.func1(p->opaque, eval_expr(p, e->param[0])); 139 case e_func1: return e->value * e->a.func1(p->opaque, eval_expr(p, e->param[0]));
139 case e_squish: return 1/(1+exp(4*eval_expr(p, e->param[0]))); 141 case e_squish: return 1/(1+exp(4*eval_expr(p, e->param[0])));
140 case e_gauss: { double d = eval_expr(p, e->param[0]); return exp(-d*d/2)/sqrt(2*M_PI); } 142 case e_gauss: { double d = eval_expr(p, e->param[0]); return exp(-d*d/2)/sqrt(2*M_PI); }
141 case e_ld: return e->value * p->var[av_clip(eval_expr(p, e->param[0]), 0, VARS-1)]; 143 case e_ld: return e->value * p->var[av_clip(eval_expr(p, e->param[0]), 0, VARS-1)];
142 case e_while: { 144 case e_while: {
143 double d = NAN; 145 double d = NAN;
144 while(eval_expr(p, e->param[0])) 146 while (eval_expr(p, e->param[0]))
145 d=eval_expr(p, e->param[1]); 147 d=eval_expr(p, e->param[1]);
146 return d; 148 return d;
147 } 149 }
148 default: { 150 default: {
149 double d = eval_expr(p, e->param[0]); 151 double d = eval_expr(p, e->param[0]);
167 return NAN; 169 return NAN;
168 } 170 }
169 171
170 static int parse_expr(AVExpr **e, Parser *p); 172 static int parse_expr(AVExpr **e, Parser *p);
171 173
172 void ff_free_expr(AVExpr * e) { 174 void ff_free_expr(AVExpr *e)
175 {
173 if (!e) return; 176 if (!e) return;
174 ff_free_expr(e->param[0]); 177 ff_free_expr(e->param[0]);
175 ff_free_expr(e->param[1]); 178 ff_free_expr(e->param[1]);
176 av_freep(&e); 179 av_freep(&e);
177 } 180 }
178 181
179 static int parse_primary(AVExpr **e, Parser *p) 182 static int parse_primary(AVExpr **e, Parser *p)
180 { 183 {
181 AVExpr * d = av_mallocz(sizeof(AVExpr)); 184 AVExpr *d = av_mallocz(sizeof(AVExpr));
182 char *next= p->s; 185 char *next= p->s;
183 int ret, i; 186 int ret, i;
184 187
185 if (!d) 188 if (!d)
186 return AVERROR(ENOMEM); 189 return AVERROR(ENOMEM);
187 190
188 /* number */ 191 /* number */
189 d->value = av_strtod(p->s, &next); 192 d->value = av_strtod(p->s, &next);
190 if(next != p->s){ 193 if (next != p->s) {
191 d->type = e_value; 194 d->type = e_value;
192 p->s= next; 195 p->s= next;
193 *e = d; 196 *e = d;
194 return 0; 197 return 0;
195 } 198 }
196 d->value = 1; 199 d->value = 1;
197 200
198 /* named constants */ 201 /* named constants */
199 for(i=0; p->const_names && p->const_names[i]; i++){ 202 for (i=0; p->const_names && p->const_names[i]; i++) {
200 if(strmatch(p->s, p->const_names[i])){ 203 if (strmatch(p->s, p->const_names[i])) {
201 p->s+= strlen(p->const_names[i]); 204 p->s+= strlen(p->const_names[i]);
202 d->type = e_const; 205 d->type = e_const;
203 d->a.const_index = i; 206 d->a.const_index = i;
204 *e = d; 207 *e = d;
205 return 0; 208 return 0;
206 } 209 }
207 } 210 }
208 211
209 p->s= strchr(p->s, '('); 212 p->s= strchr(p->s, '(');
210 if(p->s==NULL){ 213 if (p->s==NULL) {
211 av_log(p, AV_LOG_ERROR, "undefined constant or missing (\n"); 214 av_log(p, AV_LOG_ERROR, "undefined constant or missing (\n");
212 p->s= next; 215 p->s= next;
213 ff_free_expr(d); 216 ff_free_expr(d);
214 return AVERROR(EINVAL); 217 return AVERROR(EINVAL);
215 } 218 }
216 p->s++; // "(" 219 p->s++; // "("
217 if (*next == '(') { // special case do-nothing 220 if (*next == '(') { // special case do-nothing
218 av_freep(&d); 221 av_freep(&d);
219 if ((ret = parse_expr(&d, p)) < 0) 222 if ((ret = parse_expr(&d, p)) < 0)
220 return ret; 223 return ret;
221 if(p->s[0] != ')'){ 224 if (p->s[0] != ')') {
222 av_log(p, AV_LOG_ERROR, "missing )\n"); 225 av_log(p, AV_LOG_ERROR, "missing )\n");
223 ff_free_expr(d); 226 ff_free_expr(d);
224 return AVERROR(EINVAL); 227 return AVERROR(EINVAL);
225 } 228 }
226 p->s++; // ")" 229 p->s++; // ")"
229 } 232 }
230 if ((ret = parse_expr(&(d->param[0]), p)) < 0) { 233 if ((ret = parse_expr(&(d->param[0]), p)) < 0) {
231 ff_free_expr(d); 234 ff_free_expr(d);
232 return ret; 235 return ret;
233 } 236 }
234 if(p->s[0]== ','){ 237 if (p->s[0]== ',') {
235 p->s++; // "," 238 p->s++; // ","
236 parse_expr(&d->param[1], p); 239 parse_expr(&d->param[1], p);
237 } 240 }
238 if(p->s[0] != ')'){ 241 if (p->s[0] != ')') {
239 av_log(p, AV_LOG_ERROR, "missing )\n"); 242 av_log(p, AV_LOG_ERROR, "missing )\n");
240 ff_free_expr(d); 243 ff_free_expr(d);
241 return AVERROR(EINVAL); 244 return AVERROR(EINVAL);
242 } 245 }
243 p->s++; // ")" 246 p->s++; // ")"
244 247
245 d->type = e_func0; 248 d->type = e_func0;
246 if( strmatch(next, "sinh" ) ) d->a.func0 = sinh; 249 if (strmatch(next, "sinh" )) d->a.func0 = sinh;
247 else if( strmatch(next, "cosh" ) ) d->a.func0 = cosh; 250 else if (strmatch(next, "cosh" )) d->a.func0 = cosh;
248 else if( strmatch(next, "tanh" ) ) d->a.func0 = tanh; 251 else if (strmatch(next, "tanh" )) d->a.func0 = tanh;
249 else if( strmatch(next, "sin" ) ) d->a.func0 = sin; 252 else if (strmatch(next, "sin" )) d->a.func0 = sin;
250 else if( strmatch(next, "cos" ) ) d->a.func0 = cos; 253 else if (strmatch(next, "cos" )) d->a.func0 = cos;
251 else if( strmatch(next, "tan" ) ) d->a.func0 = tan; 254 else if (strmatch(next, "tan" )) d->a.func0 = tan;
252 else if( strmatch(next, "atan" ) ) d->a.func0 = atan; 255 else if (strmatch(next, "atan" )) d->a.func0 = atan;
253 else if( strmatch(next, "asin" ) ) d->a.func0 = asin; 256 else if (strmatch(next, "asin" )) d->a.func0 = asin;
254 else if( strmatch(next, "acos" ) ) d->a.func0 = acos; 257 else if (strmatch(next, "acos" )) d->a.func0 = acos;
255 else if( strmatch(next, "exp" ) ) d->a.func0 = exp; 258 else if (strmatch(next, "exp" )) d->a.func0 = exp;
256 else if( strmatch(next, "log" ) ) d->a.func0 = log; 259 else if (strmatch(next, "log" )) d->a.func0 = log;
257 else if( strmatch(next, "abs" ) ) d->a.func0 = fabs; 260 else if (strmatch(next, "abs" )) d->a.func0 = fabs;
258 else if( strmatch(next, "squish") ) d->type = e_squish; 261 else if (strmatch(next, "squish")) d->type = e_squish;
259 else if( strmatch(next, "gauss" ) ) d->type = e_gauss; 262 else if (strmatch(next, "gauss" )) d->type = e_gauss;
260 else if( strmatch(next, "mod" ) ) d->type = e_mod; 263 else if (strmatch(next, "mod" )) d->type = e_mod;
261 else if( strmatch(next, "max" ) ) d->type = e_max; 264 else if (strmatch(next, "max" )) d->type = e_max;
262 else if( strmatch(next, "min" ) ) d->type = e_min; 265 else if (strmatch(next, "min" )) d->type = e_min;
263 else if( strmatch(next, "eq" ) ) d->type = e_eq; 266 else if (strmatch(next, "eq" )) d->type = e_eq;
264 else if( strmatch(next, "gte" ) ) d->type = e_gte; 267 else if (strmatch(next, "gte" )) d->type = e_gte;
265 else if( strmatch(next, "gt" ) ) d->type = e_gt; 268 else if (strmatch(next, "gt" )) d->type = e_gt;
266 else if( strmatch(next, "lte" ) ) { AVExpr * tmp = d->param[1]; d->param[1] = d->param[0]; d->param[0] = tmp; d->type = e_gt; } 269 else if (strmatch(next, "lte" )) { AVExpr *tmp = d->param[1]; d->param[1] = d->param[0]; d->param[0] = tmp; d->type = e_gt; }
267 else if( strmatch(next, "lt" ) ) { AVExpr * tmp = d->param[1]; d->param[1] = d->param[0]; d->param[0] = tmp; d->type = e_gte; } 270 else if (strmatch(next, "lt" )) { AVExpr *tmp = d->param[1]; d->param[1] = d->param[0]; d->param[0] = tmp; d->type = e_gte; }
268 else if( strmatch(next, "ld" ) ) d->type = e_ld; 271 else if (strmatch(next, "ld" )) d->type = e_ld;
269 else if( strmatch(next, "st" ) ) d->type = e_st; 272 else if (strmatch(next, "st" )) d->type = e_st;
270 else if( strmatch(next, "while" ) ) d->type = e_while; 273 else if (strmatch(next, "while" )) d->type = e_while;
271 else { 274 else {
272 for(i=0; p->func1_names && p->func1_names[i]; i++){ 275 for (i=0; p->func1_names && p->func1_names[i]; i++) {
273 if(strmatch(next, p->func1_names[i])){ 276 if (strmatch(next, p->func1_names[i])) {
274 d->a.func1 = p->funcs1[i]; 277 d->a.func1 = p->funcs1[i];
275 d->type = e_func1; 278 d->type = e_func1;
276 *e = d; 279 *e = d;
277 return 0; 280 return 0;
278 } 281 }
279 } 282 }
280 283
281 for(i=0; p->func2_names && p->func2_names[i]; i++){ 284 for (i=0; p->func2_names && p->func2_names[i]; i++) {
282 if(strmatch(next, p->func2_names[i])){ 285 if (strmatch(next, p->func2_names[i])) {
283 d->a.func2 = p->funcs2[i]; 286 d->a.func2 = p->funcs2[i];
284 d->type = e_func2; 287 d->type = e_func2;
285 *e = d; 288 *e = d;
286 return 0; 289 return 0;
287 } 290 }
294 297
295 *e = d; 298 *e = d;
296 return 0; 299 return 0;
297 } 300 }
298 301
299 static AVExpr * new_eval_expr(int type, int value, AVExpr *p0, AVExpr *p1){ 302 static AVExpr *new_eval_expr(int type, int value, AVExpr *p0, AVExpr *p1)
300 AVExpr * e = av_mallocz(sizeof(AVExpr)); 303 {
304 AVExpr *e = av_mallocz(sizeof(AVExpr));
301 if (!e) 305 if (!e)
302 return NULL; 306 return NULL;
303 e->type =type ; 307 e->type =type ;
304 e->value =value ; 308 e->value =value ;
305 e->param[0] =p0 ; 309 e->param[0] =p0 ;
345 { 349 {
346 int ret; 350 int ret;
347 AVExpr *e0, *e1, *e2; 351 AVExpr *e0, *e1, *e2;
348 if ((ret = parse_factor(&e0, p)) < 0) 352 if ((ret = parse_factor(&e0, p)) < 0)
349 return ret; 353 return ret;
350 while(p->s[0]=='*' || p->s[0]=='/'){ 354 while (p->s[0]=='*' || p->s[0]=='/') {
351 int c= *p->s++; 355 int c= *p->s++;
352 e1 = e0; 356 e1 = e0;
353 if ((ret = parse_factor(&e2, p)) < 0) { 357 if ((ret = parse_factor(&e2, p)) < 0) {
354 ff_free_expr(e1); 358 ff_free_expr(e1);
355 return ret; 359 return ret;
369 { 373 {
370 int ret; 374 int ret;
371 AVExpr *e0, *e1, *e2; 375 AVExpr *e0, *e1, *e2;
372 if ((ret = parse_term(&e0, p)) < 0) 376 if ((ret = parse_term(&e0, p)) < 0)
373 return ret; 377 return ret;
374 while(*p->s == '+' || *p->s == '-') { 378 while (*p->s == '+' || *p->s == '-') {
375 e1 = e0; 379 e1 = e0;
376 if ((ret = parse_term(&e2, p)) < 0) { 380 if ((ret = parse_term(&e2, p)) < 0) {
377 ff_free_expr(e1); 381 ff_free_expr(e1);
378 return ret; 382 return ret;
379 } 383 }
391 395
392 static int parse_expr(AVExpr **e, Parser *p) 396 static int parse_expr(AVExpr **e, Parser *p)
393 { 397 {
394 int ret; 398 int ret;
395 AVExpr *e0, *e1, *e2; 399 AVExpr *e0, *e1, *e2;
396 if(p->stack_index <= 0) //protect against stack overflows 400 if (p->stack_index <= 0) //protect against stack overflows
397 return AVERROR(EINVAL); 401 return AVERROR(EINVAL);
398 p->stack_index--; 402 p->stack_index--;
399 403
400 if ((ret = parse_subexpr(&e0, p)) < 0) 404 if ((ret = parse_subexpr(&e0, p)) < 0)
401 return ret; 405 return ret;
402 while(*p->s == ';') { 406 while (*p->s == ';') {
403 e1 = e0; 407 e1 = e0;
404 if ((ret = parse_subexpr(&e2, p)) < 0) { 408 if ((ret = parse_subexpr(&e2, p)) < 0) {
405 ff_free_expr(e1); 409 ff_free_expr(e1);
406 return ret; 410 return ret;
407 } 411 }
417 p->stack_index++; 421 p->stack_index++;
418 *e = e0; 422 *e = e0;
419 return 0; 423 return 0;
420 } 424 }
421 425
422 static int verify_expr(AVExpr * e) { 426 static int verify_expr(AVExpr *e)
427 {
423 if (!e) return 0; 428 if (!e) return 0;
424 switch (e->type) { 429 switch (e->type) {
425 case e_value: 430 case e_value:
426 case e_const: return 1; 431 case e_const: return 1;
427 case e_func0: 432 case e_func0:
474 end: 479 end:
475 av_free(w); 480 av_free(w);
476 return ret; 481 return ret;
477 } 482 }
478 483
479 double ff_eval_expr(AVExpr *e, const double *const_values, void *opaque) { 484 double ff_eval_expr(AVExpr *e, const double *const_values, void *opaque)
485 {
480 Parser p; 486 Parser p;
481 487
482 p.const_values = const_values; 488 p.const_values = const_values;
483 p.opaque = opaque; 489 p.opaque = opaque;
484 return eval_expr(&p, e); 490 return eval_expr(&p, e);
502 return isnan(*d) ? AVERROR(EINVAL) : 0; 508 return isnan(*d) ? AVERROR(EINVAL) : 0;
503 } 509 }
504 510
505 #ifdef TEST 511 #ifdef TEST
506 #undef printf 512 #undef printf
507 static double const_values[]={ 513 static double const_values[] = {
508 M_PI, 514 M_PI,
509 M_E, 515 M_E,
510 0 516 0
511 }; 517 };
512 static const char *const_names[]={ 518 static const char *const_names[] = {
513 "PI", 519 "PI",
514 "E", 520 "E",
515 0 521 0
516 }; 522 };
517 int main(void){ 523 int main(void)
524 {
518 int i; 525 int i;
519 double d; 526 double d;
520 ff_parse_and_eval_expr(&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); 527 ff_parse_and_eval_expr(&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);
521 printf("%f == 12.7\n", d); 528 printf("%f == 12.7\n", d);
522 ff_parse_and_eval_expr(&d, "80G/80Gi", const_names, const_values, NULL, NULL, NULL, NULL, NULL, NULL); 529 ff_parse_and_eval_expr(&d, "80G/80Gi", const_names, const_values, NULL, NULL, NULL, NULL, NULL, NULL);
523 printf("%f == 0.931322575\n", d); 530 printf("%f == 0.931322575\n", d);
524 531
525 for(i=0; i<1050; i++){ 532 for (i=0; i<1050; i++) {
526 START_TIMER 533 START_TIMER
527 ff_parse_and_eval_expr(&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); 534 ff_parse_and_eval_expr(&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);
528 STOP_TIMER("ff_parse_and_eval_expr") 535 STOP_TIMER("ff_parse_and_eval_expr")
529 } 536 }
530 return 0; 537 return 0;