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>
37
44 double (*
const *
funcs1)(
void *,
double a);
// NULL terminated
46 double (*
const *
funcs2)(
void *,
double a,
double b);
// NULL terminated
54
56
58 ['y'-'E']= -24,
59 ['z'-'E']= -21,
60 ['a'-'E']= -18,
61 ['f'-'E']= -15,
62 ['p'-'E']= -12,
63 ['n'-'E']= - 9,
64 ['u'-'E']= - 6,
65 ['m'-'E']= - 3,
66 ['c'-'E']= - 2,
67 ['d'-'E']= - 1,
68 ['h'-'E']= 2,
69 ['k'-'E']= 3,
70 ['K'-'E']= 3,
71 ['M'-'E']= 6,
72 ['G'-'E']= 9,
73 ['T'-'E']= 12,
74 ['P'-'E']= 15,
75 ['E'-'E']= 18,
76 ['Z'-'E']= 21,
77 ['Y'-'E']= 24,
78 };
79
80 static const struct {
87 };
88
90 {
91 double d;
92 char *next;
93 if(numstr[0]=='0' && (numstr[1]|0x20)=='x') {
94 d = strtoul(numstr, &next, 16);
95 } else
97 /* if parsing succeeded, check for and interpret postfixes */
98 if (next!=numstr) {
99 if (next[0] == 'd' && next[1] == 'B') {
100 /* treat dB as decibels instead of decibytes */
101 d = pow(10, d / 20);
102 next += 2;
103 } else if (*next >= 'E' && *next <= 'z') {
105 if (e) {
106 if (next[1] == 'i') {
107 d*= pow( 2, e/0.3);
108 next+=2;
109 } else {
110 d*= pow(10, e);
111 next++;
112 }
113 }
114 }
115
116 if (*next=='B') {
117 d*=8;
118 next++;
119 }
120 }
121 /* if requested, fill in tail with the position after the last parsed
122 character */
123 if (tail)
124 *tail = next;
125 return d;
126 }
127
128 #define IS_IDENTIFIER_CHAR(c) ((c) - '0' <= 9U || (c) - 'a' <= 25U || (c) - 'A' <= 25U || (c) == '_')
129
131 {
132 int i;
133 for (i=0; prefix[i]; i++) {
134 if (prefix[i] != s[i]) return 0;
135 }
136 /* return 1 only if the s identifier is terminated */
138 }
139
141 enum {
150 double value;
// is sign in other types
151 union {
155 double (*
func2)(
void *, double, double);
159 };
160
162 {
164 }
165
167 {
192 }
196 av_log(p, level,
"%f\n", x);
197 return x;
198 }
202 r= r*1664525+1013904223;
204 return e->
value * (r * (1.0/UINT64_MAX));
205 }
210 return d;
211 }
213 double t = 1, d = 0,
v;
216 int i;
217 double var0 = p->
var[
id];
218 for(i=0; i<1000; i++) {
219 double ld = d;
223 if(ld==d && v)
224 break;
225 t *= x / (i+1);
226 }
228 return d;
229 }
231 int i, j;
232 double low = -1, high = -1,
v, low_v = -DBL_MAX, high_v = DBL_MAX;
233 double var0 = p->
var[0];
235 for(i=-1; i<1024; i++) {
236 if(i<255) {
238 } else {
239 p->
var[0] = x_max*pow(0.9, i-255);
240 if (i&1) p->
var[0] *= -1;
241 if (i&2) p->
var[0] += low;
242 else p->
var[0] += high;
243 }
245 if (v<=0 && v>low_v) {
248 }
249 if (
v>=0 &&
v<high_v) {
252 }
253 if (low>=0 && high>=0){
254 for (j=0; j<1000; j++) {
255 p->
var[0] = (low+high)*0.5;
256 if (low == p->
var[0] || high == p->
var[0])
257 break;
259 if (
v<=0) low = p->
var[0];
260 if (
v>=0) high= p->
var[0];
263 break;
264 }
265 }
266 break;
267 }
268 }
270 return -low_v<high_v ? low : high;
271 }
272 default: {
276 case e_mod:
return e->
value * (d - floor((!CONFIG_FTRAPV || d2) ? d / d2 : d *
INFINITY) * d2);
278 case e_max:
return e->
value * (d > d2 ? d : d2);
279 case e_min:
return e->
value * (d < d2 ? d : d2);
280 case e_eq:
return e->
value * (d == d2 ? 1.0 : 0.0);
281 case e_gt:
return e->
value * (d > d2 ? 1.0 : 0.0);
282 case e_gte:
return e->
value * (d >= d2 ? 1.0 : 0.0);
283 case e_lt:
return e->
value * (d < d2 ? 1.0 : 0.0);
284 case e_lte:
return e->
value * (d <= d2 ? 1.0 : 0.0);
294 }
295 }
296 }
298 }
299
301
303 {
304 if (!e) return;
310 }
311
313 {
315 char *next = p->
s, *
s0 = p->
s;
317
318 if (!d)
320
321 /* number */
326 *e = d;
327 return 0;
328 }
330
331 /* named constants */
337 *e = d;
338 return 0;
339 }
340 }
346 *e = d;
347 return 0;
348 }
349 }
350
351 p->
s= strchr(p->
s,
'(');
357 }
359 if (*next == '(') { // special case do-nothing
363 if (p->
s[0] !=
')') {
367 }
369 *e = d;
370 return 0;
371 }
375 }
379 }
383 }
384 if (p->
s[0] !=
')') {
388 }
390
437 else {
442 *e = d;
443 return 0;
444 }
445 }
446
451 *e = d;
452 return 0;
453 }
454 }
455
459 }
460
461 *e = d;
462 return 0;
463 }
464
466 {
468 if (!e)
469 return NULL;
474 return e;
475 }
476
478 {
479 *sign= (*p->
s ==
'+') - (*p->
s ==
'-');
482 }
483
485 {
486 /* do not filter out the negative sign when parsing a dB value.
487 for example, -3dB is not the same as -(3dB) */
489 char *next;
491 if (next != p->
s && next[0] ==
'd' && next[1] ==
'B') {
492 *sign = 0;
494 }
495 }
497 }
498
500 {
501 int sign, sign2,
ret;
503 if ((ret =
parse_dB(&e0, p, &sign)) < 0)
506 e1 = e0;
508 if ((ret =
parse_dB(&e2, p, &sign2)) < 0) {
511 }
513 if (!e0) {
517 }
519 }
520 if (e0) e0->
value *= (sign|1);
521
522 *e = e0;
523 return 0;
524 }
525
527 {
532 while (p->
s[0]==
'*' || p->
s[0]==
'/') {
534 e1 = e0;
538 }
540 if (!e0) {
544 }
545 }
546 *e = e0;
547 return 0;
548 }
549
551 {
556 while (*p->
s ==
'+' || *p->
s ==
'-') {
557 e1 = e0;
561 }
563 if (!e0) {
567 }
568 };
569
570 *e = e0;
571 return 0;
572 }
573
575 {
578 if (p->
stack_index <= 0)
//protect against stack overflows
581
584 while (*p->
s ==
';') {
586 e1 = e0;
590 }
592 if (!e0) {
596 }
597 };
598
600 *e = e0;
601 return 0;
602 }
603
605 {
606 if (!e) return 0;
637 }
638 }
639
643 const char * const *func2_names, double (* const *funcs2)(void *, double, double),
644 int log_offset, void *log_ctx)
645 {
649 char *wp = w;
652
653 if (!w)
655
656 while (*s)
658 *wp++ = 0;
659
670
678 }
683 }
685 *expr = e;
689 }
690
692 {
695
699 }
700
702 const char *
const *const_names,
const double *
const_values,
703 const char *
const *func1_names,
double (*
const *
funcs1)(
void *,
double),
704 const char * const *func2_names, double (* const *funcs2)(void *, double, double),
705 void *opaque, int log_offset, void *log_ctx)
706 {
708 int ret =
av_expr_parse(&e, s, const_names, func1_names,
funcs1, func2_names, funcs2, log_offset, log_ctx);
709
710 if (ret < 0) {
713 }
717 }
718
719 #ifdef TEST
720 #include <string.h>
721
722 static const double const_values[] = {
725 0
726 };
727
728 static const char *const const_names[] = {
729 "PI",
730 "E",
731 0
732 };
733
734 int main(
int argc,
char **argv)
735 {
736 int i;
737 double d;
738 const char *const *expr;
739 static const char *const exprs[] = {
740 "",
741 "1;2",
742 "-20",
743 "-PI",
744 "+PI",
745 "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
746 "80G/80Gi",
747 "1k",
748 "1Gi",
749 "1gi",
750 "1GiFoo",
751 "1k+1k",
752 "1Gi*3foo",
753 "foo",
754 "foo(",
755 "foo()",
756 "foo)",
757 "sin",
758 "sin(",
759 "sin()",
760 "sin)",
761 "sin 10",
762 "sin(1,2,3)",
763 "sin(1 )",
764 "1",
765 "1foo",
766 "bar + PI + E + 100f*2 + foo",
767 "13k + 12f - foo(1, 2)",
768 "1gi",
769 "1Gi",
770 "st(0, 123)",
771 "st(1, 123); ld(1)",
772 "lte(0, 1)",
773 "lte(1, 1)",
774 "lte(1, 0)",
775 "lt(0, 1)",
776 "lt(1, 1)",
777 "gt(1, 0)",
778 "gt(2, 7)",
779 "gte(122, 122)",
780 /* compute 1+2+...+N */
781 "st(0, 1); while(lte(ld(0), 100), st(1, ld(1)+ld(0));st(0, ld(0)+1)); ld(1)",
782 /* compute Fib(N) */
783 "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)",
784 "while(0, 10)",
785 "st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))",
786 "isnan(1)",
787 "isnan(NAN)",
788 "isnan(INF)",
789 "isinf(1)",
790 "isinf(NAN)",
791 "isinf(INF)",
792 "floor(NAN)",
793 "floor(123.123)",
794 "floor(-123.123)",
795 "trunc(123.123)",
796 "trunc(-123.123)",
797 "ceil(123.123)",
798 "ceil(-123.123)",
799 "sqrt(1764)",
800 "isnan(sqrt(-1))",
801 "not(1)",
802 "not(NAN)",
803 "not(0)",
804 "6.0206dB",
805 "-3.0103dB",
806 "pow(0,1.23)",
807 "pow(PI,1.23)",
808 "PI^1.23",
809 "pow(-1,1.23)",
810 "if(1, 2)",
811 "if(1, 1, 2)",
812 "if(0, 1, 2)",
813 "ifnot(0, 23)",
814 "ifnot(1, NaN) + if(0, 1)",
815 "ifnot(1, 1, 2)",
816 "ifnot(0, 1, 2)",
817 "taylor(1, 1)",
818 "taylor(eq(mod(ld(1),4),1)-eq(mod(ld(1),4),3), PI/2, 1)",
819 "root(sin(ld(0))-1, 2)",
820 "root(sin(ld(0))+6+sin(ld(0)/12)-log(ld(0)), 100)",
821 "7000000B*random(0)",
822 "squish(2)",
823 "gauss(0.1)",
824 "hypot(4,3)",
825 "gcd(30,55)*print(min(9,1))",
826 "bitor(42, 12)",
827 "bitand(42, 12)",
828 "bitand(NAN, 1)",
829 "between(10, -3, 10)",
830 "between(-4, -2, -1)",
831 "between(1,2)",
832 NULL
833 };
834
835 for (expr = exprs; *expr; expr++) {
836 printf("Evaluating '%s'\n", *expr);
838 const_names, const_values,
839 NULL, NULL, NULL, NULL, NULL, 0, NULL);
841 printf("'%s' -> nan\n\n", *expr);
842 else
843 printf("'%s' -> %f\n\n", *expr, d);
844 }
845
847 const_names, const_values,
848 NULL, NULL, NULL, NULL, NULL, 0, NULL);
849 printf("%f == 12.7\n", d);
851 const_names, const_values,
852 NULL, NULL, NULL, NULL, NULL, 0, NULL);
853 printf("%f == 0.931322575\n", d);
854
855 if (argc > 1 && !strcmp(argv[1], "-t")) {
856 for (i = 0; i < 1050; i++) {
859 const_names, const_values,
860 NULL, NULL, NULL, NULL, NULL, 0, NULL);
862 }
863 }
864
865 return 0;
866 }
867 #endif