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
29 #include <float.h>
38
45 double (*
const *
funcs1)(
void *,
double a);
// NULL terminated
47 double (*
const *
funcs2)(
void *,
double a,
double b);
// NULL terminated
55
57
59 ['y'-'E']= -24,
60 ['z'-'E']= -21,
61 ['a'-'E']= -18,
62 ['f'-'E']= -15,
63 ['p'-'E']= -12,
64 ['n'-'E']= - 9,
65 ['u'-'E']= - 6,
66 ['m'-'E']= - 3,
67 ['c'-'E']= - 2,
68 ['d'-'E']= - 1,
69 ['h'-'E']= 2,
70 ['k'-'E']= 3,
71 ['K'-'E']= 3,
72 ['M'-'E']= 6,
73 ['G'-'E']= 9,
74 ['T'-'E']= 12,
75 ['P'-'E']= 15,
76 ['E'-'E']= 18,
77 ['Z'-'E']= 21,
78 ['Y'-'E']= 24,
79 };
80
81 static const struct {
88 };
89
91 {
92 double d;
93 char *next;
94 if(numstr[0]=='0' && (numstr[1]|0x20)=='x') {
95 d = strtoul(numstr, &next, 16);
96 } else
98 /* if parsing succeeded, check for and interpret postfixes */
99 if (next!=numstr) {
100 if (next[0] == 'd' && next[1] == 'B') {
101 /* treat dB as decibels instead of decibytes */
102 d = pow(10, d / 20);
103 next += 2;
104 } else if (*next >= 'E' && *next <= 'z') {
106 if (e) {
107 if (next[1] == 'i') {
108 d*= pow( 2, e/0.3);
109 next+=2;
110 } else {
111 d*= pow(10, e);
112 next++;
113 }
114 }
115 }
116
117 if (*next=='B') {
118 d*=8;
119 next++;
120 }
121 }
122 /* if requested, fill in tail with the position after the last parsed
123 character */
124 if (tail)
125 *tail = next;
126 return d;
127 }
128
129 #define IS_IDENTIFIER_CHAR(c) ((c) - '0' <= 9U || (c) - 'a' <= 25U || (c) - 'A' <= 25U || (c) == '_')
130
132 {
133 int i;
134 for (i=0; prefix[i]; i++) {
135 if (prefix[i] != s[i]) return 0;
136 }
137 /* return 1 only if the s identifier is terminated */
139 }
140
142 enum {
151 double value;
// is sign in other types
152 union {
156 double (*
func2)(
void *, double, double);
160 };
161
163 {
165 }
166
168 {
193 }
197 av_log(p, level,
"%f\n", x);
198 return x;
199 }
203 r= r*1664525+1013904223;
205 return e->
value * (r * (1.0/UINT64_MAX));
206 }
211 return d;
212 }
214 double t = 1, d = 0,
v;
217 int i;
218 double var0 = p->
var[
id];
219 for(i=0; i<1000; i++) {
220 double ld = d;
224 if(ld==d && v)
225 break;
226 t *= x / (i+1);
227 }
229 return d;
230 }
232 int i, j;
233 double low = -1, high = -1,
v, low_v = -DBL_MAX, high_v = DBL_MAX;
234 double var0 = p->
var[0];
236 for(i=-1; i<1024; i++) {
237 if(i<255) {
239 } else {
240 p->
var[0] = x_max*pow(0.9, i-255);
241 if (i&1) p->
var[0] *= -1;
242 if (i&2) p->
var[0] += low;
243 else p->
var[0] += high;
244 }
246 if (v<=0 && v>low_v) {
249 }
250 if (
v>=0 &&
v<high_v) {
253 }
254 if (low>=0 && high>=0){
255 for (j=0; j<1000; j++) {
256 p->
var[0] = (low+high)*0.5;
257 if (low == p->
var[0] || high == p->
var[0])
258 break;
260 if (
v<=0) low = p->
var[0];
261 if (
v>=0) high= p->
var[0];
264 break;
265 }
266 }
267 break;
268 }
269 }
271 return -low_v<high_v ? low : high;
272 }
273 default: {
277 case e_mod:
return e->
value * (d - floor((!CONFIG_FTRAPV || d2) ? d / d2 : d *
INFINITY) * d2);
279 case e_max:
return e->
value * (d > d2 ? d : d2);
280 case e_min:
return e->
value * (d < d2 ? d : d2);
281 case e_eq:
return e->
value * (d == d2 ? 1.0 : 0.0);
282 case e_gt:
return e->
value * (d > d2 ? 1.0 : 0.0);
283 case e_gte:
return e->
value * (d >= d2 ? 1.0 : 0.0);
284 case e_lt:
return e->
value * (d < d2 ? 1.0 : 0.0);
285 case e_lte:
return e->
value * (d <= d2 ? 1.0 : 0.0);
295 }
296 }
297 }
299 }
300
302
304 {
305 if (!e) return;
311 }
312
314 {
316 char *next = p->
s, *
s0 = p->
s;
318
319 if (!d)
321
322 /* number */
327 *e = d;
328 return 0;
329 }
331
332 /* named constants */
338 *e = d;
339 return 0;
340 }
341 }
347 *e = d;
348 return 0;
349 }
350 }
351
352 p->
s= strchr(p->
s,
'(');
358 }
360 if (*next == '(') { // special case do-nothing
364 if (p->
s[0] !=
')') {
368 }
370 *e = d;
371 return 0;
372 }
376 }
380 }
384 }
385 if (p->
s[0] !=
')') {
389 }
391
438 else {
443 *e = d;
444 return 0;
445 }
446 }
447
452 *e = d;
453 return 0;
454 }
455 }
456
460 }
461
462 *e = d;
463 return 0;
464 }
465
467 {
469 if (!e)
470 return NULL;
475 return e;
476 }
477
479 {
480 *sign= (*p->
s ==
'+') - (*p->
s ==
'-');
483 }
484
486 {
487 /* do not filter out the negative sign when parsing a dB value.
488 for example, -3dB is not the same as -(3dB) */
490 char *next;
492 if (next != p->
s && next[0] ==
'd' && next[1] ==
'B') {
493 *sign = 0;
495 }
496 }
498 }
499
501 {
502 int sign, sign2,
ret;
504 if ((ret =
parse_dB(&e0, p, &sign)) < 0)
507 e1 = e0;
509 if ((ret =
parse_dB(&e2, p, &sign2)) < 0) {
512 }
514 if (!e0) {
518 }
520 }
521 if (e0) e0->
value *= (sign|1);
522
523 *e = e0;
524 return 0;
525 }
526
528 {
533 while (p->
s[0]==
'*' || p->
s[0]==
'/') {
535 e1 = e0;
539 }
541 if (!e0) {
545 }
546 }
547 *e = e0;
548 return 0;
549 }
550
552 {
557 while (*p->
s ==
'+' || *p->
s ==
'-') {
558 e1 = e0;
562 }
564 if (!e0) {
568 }
569 };
570
571 *e = e0;
572 return 0;
573 }
574
576 {
579 if (p->
stack_index <= 0)
//protect against stack overflows
582
585 while (*p->
s ==
';') {
587 e1 = e0;
591 }
593 if (!e0) {
597 }
598 };
599
601 *e = e0;
602 return 0;
603 }
604
606 {
607 if (!e) return 0;
638 }
639 }
640
644 const char * const *func2_names, double (* const *funcs2)(void *, double, double),
645 int log_offset, void *log_ctx)
646 {
650 char *wp = w;
653
654 if (!w)
656
657 while (*s)
659 *wp++ = 0;
660
671
679 }
684 }
686 *expr = e;
690 }
691
693 {
696
700 }
701
703 const char *
const *const_names,
const double *
const_values,
704 const char *
const *func1_names,
double (*
const *
funcs1)(
void *,
double),
705 const char * const *func2_names, double (* const *funcs2)(void *, double, double),
706 void *opaque, int log_offset, void *log_ctx)
707 {
709 int ret =
av_expr_parse(&e, s, const_names, func1_names,
funcs1, func2_names, funcs2, log_offset, log_ctx);
710
711 if (ret < 0) {
714 }
718 }
719
720 #ifdef TEST
721 #include <string.h>
722
723 static const double const_values[] = {
726 0
727 };
728
729 static const char *const const_names[] = {
730 "PI",
731 "E",
732 0
733 };
734
735 int main(
int argc,
char **argv)
736 {
737 int i;
738 double d;
739 const char *const *expr;
740 static const char *const exprs[] = {
741 "",
742 "1;2",
743 "-20",
744 "-PI",
745 "+PI",
746 "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
747 "80G/80Gi",
748 "1k",
749 "1Gi",
750 "1gi",
751 "1GiFoo",
752 "1k+1k",
753 "1Gi*3foo",
754 "foo",
755 "foo(",
756 "foo()",
757 "foo)",
758 "sin",
759 "sin(",
760 "sin()",
761 "sin)",
762 "sin 10",
763 "sin(1,2,3)",
764 "sin(1 )",
765 "1",
766 "1foo",
767 "bar + PI + E + 100f*2 + foo",
768 "13k + 12f - foo(1, 2)",
769 "1gi",
770 "1Gi",
771 "st(0, 123)",
772 "st(1, 123); ld(1)",
773 "lte(0, 1)",
774 "lte(1, 1)",
775 "lte(1, 0)",
776 "lt(0, 1)",
777 "lt(1, 1)",
778 "gt(1, 0)",
779 "gt(2, 7)",
780 "gte(122, 122)",
781 /* compute 1+2+...+N */
782 "st(0, 1); while(lte(ld(0), 100), st(1, ld(1)+ld(0));st(0, ld(0)+1)); ld(1)",
783 /* compute Fib(N) */
784 "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)",
785 "while(0, 10)",
786 "st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))",
787 "isnan(1)",
788 "isnan(NAN)",
789 "isnan(INF)",
790 "isinf(1)",
791 "isinf(NAN)",
792 "isinf(INF)",
793 "floor(NAN)",
794 "floor(123.123)",
795 "floor(-123.123)",
796 "trunc(123.123)",
797 "trunc(-123.123)",
798 "ceil(123.123)",
799 "ceil(-123.123)",
800 "sqrt(1764)",
801 "isnan(sqrt(-1))",
802 "not(1)",
803 "not(NAN)",
804 "not(0)",
805 "6.0206dB",
806 "-3.0103dB",
807 "pow(0,1.23)",
808 "pow(PI,1.23)",
809 "PI^1.23",
810 "pow(-1,1.23)",
811 "if(1, 2)",
812 "if(1, 1, 2)",
813 "if(0, 1, 2)",
814 "ifnot(0, 23)",
815 "ifnot(1, NaN) + if(0, 1)",
816 "ifnot(1, 1, 2)",
817 "ifnot(0, 1, 2)",
818 "taylor(1, 1)",
819 "taylor(eq(mod(ld(1),4),1)-eq(mod(ld(1),4),3), PI/2, 1)",
820 "root(sin(ld(0))-1, 2)",
821 "root(sin(ld(0))+6+sin(ld(0)/12)-log(ld(0)), 100)",
822 "7000000B*random(0)",
823 "squish(2)",
824 "gauss(0.1)",
825 "hypot(4,3)",
826 "gcd(30,55)*print(min(9,1))",
827 "bitor(42, 12)",
828 "bitand(42, 12)",
829 "bitand(NAN, 1)",
830 "between(10, -3, 10)",
831 "between(-4, -2, -1)",
832 "between(1,2)",
833 NULL
834 };
835
836 for (expr = exprs; *expr; expr++) {
837 printf("Evaluating '%s'\n", *expr);
839 const_names, const_values,
840 NULL, NULL, NULL, NULL, NULL, 0, NULL);
842 printf("'%s' -> nan\n\n", *expr);
843 else
844 printf("'%s' -> %f\n\n", *expr, d);
845 }
846
848 const_names, const_values,
849 NULL, NULL, NULL, NULL, NULL, 0, NULL);
850 printf("%f == 12.7\n", d);
852 const_names, const_values,
853 NULL, NULL, NULL, NULL, NULL, 0, NULL);
854 printf("%f == 0.931322575\n", d);
855
856 if (argc > 1 && !strcmp(argv[1], "-t")) {
857 for (i = 0; i < 1050; i++) {
860 const_names, const_values,
861 NULL, NULL, NULL, NULL, NULL, 0, NULL);
863 }
864 }
865
866 return 0;
867 }
868 #endif