1 /*
2 * Copyright (c) 2002-2006 Michael Niedermayer <michaelni@gmx.at>
3 * Copyright (c) 2006 Oded Shimon <ods15@ods15.dyndns.org>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * simple arithmetic expression evaluator.
25 *
26 * see http://joe.hotchkiss.com/programming/eval/eval.html
27 */
28
39
46 double (*
const *
funcs1)(
void *,
double a);
// NULL terminated
48 double (*
const *
funcs2)(
void *,
double a,
double b);
// NULL terminated
56
58
60 ['y'-'E']= -24,
61 ['z'-'E']= -21,
62 ['a'-'E']= -18,
63 ['f'-'E']= -15,
64 ['p'-'E']= -12,
65 ['n'-'E']= - 9,
66 ['u'-'E']= - 6,
67 ['m'-'E']= - 3,
68 ['c'-'E']= - 2,
69 ['d'-'E']= - 1,
70 ['h'-'E']= 2,
71 ['k'-'E']= 3,
72 ['K'-'E']= 3,
73 ['M'-'E']= 6,
74 ['G'-'E']= 9,
75 ['T'-'E']= 12,
76 ['P'-'E']= 15,
77 ['E'-'E']= 18,
78 ['Z'-'E']= 21,
79 ['Y'-'E']= 24,
80 };
81
82 static const struct {
90 };
91
93 {
94 double d;
95 char *next;
96 if(numstr[0]=='0' && (numstr[1]|0x20)=='x') {
97 d = strtoul(numstr, &next, 16);
98 } else
100 /* if parsing succeeded, check for and interpret postfixes */
101 if (next!=numstr) {
102 if (next[0] == 'd' && next[1] == 'B') {
103 /* treat dB as decibels instead of decibytes */
104 d = pow(10, d / 20);
105 next += 2;
106 } else if (*next >= 'E' && *next <= 'z') {
108 if (e) {
109 if (next[1] == 'i') {
110 d*= pow( 2, e/0.3);
111 next+=2;
112 } else {
113 d*= pow(10, e);
114 next++;
115 }
116 }
117 }
118
119 if (*next=='B') {
120 d*=8;
121 next++;
122 }
123 }
124 /* if requested, fill in tail with the position after the last parsed
125 character */
126 if (tail)
127 *tail = next;
128 return d;
129 }
130
131 #define IS_IDENTIFIER_CHAR(c) ((c) - '0' <= 9U || (c) - 'a' <= 25U || (c) - 'A' <= 25U || (c) == '_')
132
134 {
135 int i;
136 for (i=0; prefix[i]; i++) {
137 if (prefix[i] != s[i]) return 0;
138 }
139 /* return 1 only if the s identifier is terminated */
141 }
142
144 enum {
153 double value;
// is sign in other types
154 union {
158 double (*
func2)(
void *, double, double);
162 };
163
165 {
167 }
168
170 {
197 }
202 }
206 av_log(p, level,
"%f\n", x);
207 return x;
208 }
212 r= r*1664525+1013904223;
214 return e->
value * (r * (1.0/UINT64_MAX));
215 }
220 return d;
221 }
223 double t = 1, d = 0,
v;
226 int i;
227 double var0 = p->
var[
id];
228 for(i=0; i<1000; i++) {
229 double ld = d;
233 if(ld==d && v)
234 break;
235 t *= x / (i+1);
236 }
238 return d;
239 }
241 int i, j;
242 double low = -1, high = -1,
v, low_v = -DBL_MAX, high_v = DBL_MAX;
243 double var0 = p->
var[0];
245 for(i=-1; i<1024; i++) {
246 if(i<255) {
248 } else {
249 p->
var[0] = x_max*pow(0.9, i-255);
250 if (i&1) p->
var[0] *= -1;
251 if (i&2) p->
var[0] += low;
252 else p->
var[0] += high;
253 }
255 if (v<=0 && v>low_v) {
258 }
259 if (
v>=0 &&
v<high_v) {
262 }
263 if (low>=0 && high>=0){
264 for (j=0; j<1000; j++) {
265 p->
var[0] = (low+high)*0.5;
266 if (low == p->
var[0] || high == p->
var[0])
267 break;
269 if (
v<=0) low = p->
var[0];
270 if (
v>=0) high= p->
var[0];
273 break;
274 }
275 }
276 break;
277 }
278 }
280 return -low_v<high_v ? low : high;
281 }
282 default: {
286 case e_mod:
return e->
value * (d - floor((!CONFIG_FTRAPV || d2) ? d / d2 : d *
INFINITY) * d2);
288 case e_max:
return e->
value * (d > d2 ? d : d2);
289 case e_min:
return e->
value * (d < d2 ? d : d2);
290 case e_eq:
return e->
value * (d == d2 ? 1.0 : 0.0);
291 case e_gt:
return e->
value * (d > d2 ? 1.0 : 0.0);
292 case e_gte:
return e->
value * (d >= d2 ? 1.0 : 0.0);
293 case e_lt:
return e->
value * (d < d2 ? 1.0 : 0.0);
294 case e_lte:
return e->
value * (d <= d2 ? 1.0 : 0.0);
304 }
305 }
306 }
308 }
309
311
313 {
314 if (!e) return;
320 }
321
323 {
325 char *next = p->
s, *
s0 = p->
s;
327
328 if (!d)
330
331 /* number */
336 *e = d;
337 return 0;
338 }
340
341 /* named constants */
347 *e = d;
348 return 0;
349 }
350 }
356 *e = d;
357 return 0;
358 }
359 }
360
361 p->
s= strchr(p->
s,
'(');
367 }
369 if (*next == '(') { // special case do-nothing
373 if (p->
s[0] !=
')') {
377 }
379 *e = d;
380 return 0;
381 }
385 }
389 }
393 }
394 if (p->
s[0] !=
')') {
398 }
400
448 else {
453 *e = d;
454 return 0;
455 }
456 }
457
462 *e = d;
463 return 0;
464 }
465 }
466
470 }
471
472 *e = d;
473 return 0;
474 }
475
477 {
479 if (!e)
480 return NULL;
485 return e;
486 }
487
489 {
490 *sign= (*p->
s ==
'+') - (*p->
s ==
'-');
493 }
494
496 {
497 /* do not filter out the negative sign when parsing a dB value.
498 for example, -3dB is not the same as -(3dB) */
500 char *next;
502 if (next != p->
s && next[0] ==
'd' && next[1] ==
'B') {
503 *sign = 0;
505 }
506 }
508 }
509
511 {
512 int sign, sign2,
ret;
514 if ((ret =
parse_dB(&e0, p, &sign)) < 0)
517 e1 = e0;
519 if ((ret =
parse_dB(&e2, p, &sign2)) < 0) {
522 }
524 if (!e0) {
528 }
530 }
531 if (e0) e0->
value *= (sign|1);
532
533 *e = e0;
534 return 0;
535 }
536
538 {
543 while (p->
s[0]==
'*' || p->
s[0]==
'/') {
545 e1 = e0;
549 }
551 if (!e0) {
555 }
556 }
557 *e = e0;
558 return 0;
559 }
560
562 {
567 while (*p->
s ==
'+' || *p->
s ==
'-') {
568 e1 = e0;
572 }
574 if (!e0) {
578 }
579 };
580
581 *e = e0;
582 return 0;
583 }
584
586 {
589 if (p->
stack_index <= 0)
//protect against stack overflows
592
595 while (*p->
s ==
';') {
597 e1 = e0;
601 }
603 if (!e0) {
607 }
608 };
609
611 *e = e0;
612 return 0;
613 }
614
616 {
617 if (!e) return 0;
649 }
650 }
651
653 const char * const *const_names,
655 const char * const *func2_names, double (* const *funcs2)(void *, double, double),
656 int log_offset, void *log_ctx)
657 {
661 char *wp = w;
664
665 if (!w)
667
668 while (*s)
670 *wp++ = 0;
671
682
690 }
695 }
697 *expr = e;
701 }
702
704 {
707
711 }
712
714 const char * const *const_names, const double *const_values,
715 const char *
const *func1_names,
double (*
const *
funcs1)(
void *,
double),
716 const char * const *func2_names, double (* const *funcs2)(void *, double, double),
717 void *opaque, int log_offset, void *log_ctx)
718 {
720 int ret =
av_expr_parse(&e, s, const_names, func1_names,
funcs1, func2_names, funcs2, log_offset, log_ctx);
721
722 if (ret < 0) {
725 }
729 }
730
731 #ifdef TEST
732 #include <string.h>
733
734 static const double const_values[] = {
737 0
738 };
739
740 static const char *const const_names[] = {
741 "PI",
742 "E",
743 0
744 };
745
746 int main(
int argc,
char **argv)
747 {
748 int i;
749 double d;
750 const char *const *expr;
751 static const char *const exprs[] = {
752 "",
753 "1;2",
754 "-20",
755 "-PI",
756 "+PI",
757 "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
758 "80G/80Gi",
759 "1k",
760 "1Gi",
761 "1gi",
762 "1GiFoo",
763 "1k+1k",
764 "1Gi*3foo",
765 "foo",
766 "foo(",
767 "foo()",
768 "foo)",
769 "sin",
770 "sin(",
771 "sin()",
772 "sin)",
773 "sin 10",
774 "sin(1,2,3)",
775 "sin(1 )",
776 "1",
777 "1foo",
778 "bar + PI + E + 100f*2 + foo",
779 "13k + 12f - foo(1, 2)",
780 "1gi",
781 "1Gi",
782 "st(0, 123)",
783 "st(1, 123); ld(1)",
784 "lte(0, 1)",
785 "lte(1, 1)",
786 "lte(1, 0)",
787 "lt(0, 1)",
788 "lt(1, 1)",
789 "gt(1, 0)",
790 "gt(2, 7)",
791 "gte(122, 122)",
792 /* compute 1+2+...+N */
793 "st(0, 1); while(lte(ld(0), 100), st(1, ld(1)+ld(0));st(0, ld(0)+1)); ld(1)",
794 /* compute Fib(N) */
795 "st(1, 1); st(2, 2); st(0, 1); while(lte(ld(0),10), st(3, ld(1)+ld(2)); st(1, ld(2)); st(2, ld(3)); st(0, ld(0)+1)); ld(3)",
796 "while(0, 10)",
797 "st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))",
798 "isnan(1)",
799 "isnan(NAN)",
800 "isnan(INF)",
801 "isinf(1)",
802 "isinf(NAN)",
803 "isinf(INF)",
804 "floor(NAN)",
805 "floor(123.123)",
806 "floor(-123.123)",
807 "trunc(123.123)",
808 "trunc(-123.123)",
809 "ceil(123.123)",
810 "ceil(-123.123)",
811 "sqrt(1764)",
812 "isnan(sqrt(-1))",
813 "not(1)",
814 "not(NAN)",
815 "not(0)",
816 "6.0206dB",
817 "-3.0103dB",
818 "pow(0,1.23)",
819 "pow(PI,1.23)",
820 "PI^1.23",
821 "pow(-1,1.23)",
822 "if(1, 2)",
823 "if(1, 1, 2)",
824 "if(0, 1, 2)",
825 "ifnot(0, 23)",
826 "ifnot(1, NaN) + if(0, 1)",
827 "ifnot(1, 1, 2)",
828 "ifnot(0, 1, 2)",
829 "taylor(1, 1)",
830 "taylor(eq(mod(ld(1),4),1)-eq(mod(ld(1),4),3), PI/2, 1)",
831 "root(sin(ld(0))-1, 2)",
832 "root(sin(ld(0))+6+sin(ld(0)/12)-log(ld(0)), 100)",
833 "7000000B*random(0)",
834 "squish(2)",
835 "gauss(0.1)",
836 "hypot(4,3)",
837 "gcd(30,55)*print(min(9,1))",
838 "bitor(42, 12)",
839 "bitand(42, 12)",
840 "bitand(NAN, 1)",
841 "between(10, -3, 10)",
842 "between(-4, -2, -1)",
843 "between(1,2)",
844 "clip(0, 2, 1)",
845 "clip(0/0, 1, 2)",
846 "clip(0, 0/0, 1)",
847 NULL
848 };
849
850 for (expr = exprs; *expr; expr++) {
851 printf("Evaluating '%s'\n", *expr);
853 const_names, const_values,
854 NULL, NULL, NULL, NULL, NULL, 0, NULL);
856 printf("'%s' -> nan\n\n", *expr);
857 else
858 printf("'%s' -> %f\n\n", *expr, d);
859 }
860
862 const_names, const_values,
863 NULL, NULL, NULL, NULL, NULL, 0, NULL);
864 printf("%f == 12.7\n", d);
866 const_names, const_values,
867 NULL, NULL, NULL, NULL, NULL, 0, NULL);
868 printf("%f == 0.931322575\n", d);
869
870 if (argc > 1 && !strcmp(argv[1], "-t")) {
871 for (i = 0; i < 1050; i++) {
874 const_names, const_values,
875 NULL, NULL, NULL, NULL, NULL, 0, NULL);
877 }
878 }
879
880 return 0;
881 }
882 #endif