Subversion Repositories filter_foundry

Rev

Rev 288 | Rev 532 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 288 Rev 301
1
/*
1
/*
2
    This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
2
    This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
3
    Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
3
    Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
4
    Copyright (C) 2018-2021 Daniel Marschall, ViaThinkSoft
4
    Copyright (C) 2018-2021 Daniel Marschall, ViaThinkSoft
5
 
5
 
6
    This program is free software; you can redistribute it and/or modify
6
    This program is free software; you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation; either version 2 of the License, or
8
    the Free Software Foundation; either version 2 of the License, or
9
    (at your option) any later version.
9
    (at your option) any later version.
10
 
10
 
11
    This program is distributed in the hope that it will be useful,
11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
14
    GNU General Public License for more details.
15
 
15
 
16
    You should have received a copy of the GNU General Public License
16
    You should have received a copy of the GNU General Public License
17
    along with this program; if not, write to the Free Software
17
    along with this program; if not, write to the Free Software
18
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
*/
19
*/
20
 
20
 
21
#include <stdlib.h>
21
#include <stdlib.h>
22
#include <stdio.h>
22
#include <stdio.h>
23
#include <math.h>
23
#include <math.h>
24
 
24
 
25
// The following ugly workaround is obviated by Carbon StdCLib headers;
25
// The following ugly workaround is obviated by Carbon StdCLib headers;
26
// see: https://web.archive.org/web/20041031134219/http://developer.apple.com/tools/mpw-tools/relnotes/carbonstdclib.html
26
// see: https://web.archive.org/web/20041031134219/http://developer.apple.com/tools/mpw-tools/relnotes/carbonstdclib.html
27
 
27
 
28
//#ifdef TARGET_API_MAC_CARBON
28
//#ifdef TARGET_API_MAC_CARBON
29
//      /* can't use StdCLib ctype.h, it refers to symbols which aren't in OS X stdclib */
29
//      /* can't use StdCLib ctype.h, it refers to symbols which aren't in OS X stdclib */
30
//      int isprint(int);
30
//      int isprint(int);
31
//#else
31
//#else
32
        #include <ctype.h>
32
        #include <ctype.h>
33
//#endif
33
//#endif
34
 
34
 
35
#include "node.h"
35
#include "node.h"
36
#include "y.tab.h"
36
#include "y.tab.h"
37
#include "funcs.h"
37
#include "funcs.h"
38
 
38
 
39
void freenodes(struct node *p);
39
void freenodes(struct node *p);
40
 
40
 
41
int varused[0x100],allocs; /* one flag per special variable, indicating if it's used */
41
int varused[0x100],allocs; /* one flag per special variable, indicating if it's used */
42
value_type var[0x100];
42
value_type var[0x100];
43
 
43
 
44
struct node *node_list;
44
struct node *node_list;
45
 
45
 
46
struct node *newnode(int k){
46
struct node *newnode(int k){
47
        struct node *p;
47
        struct node *p;
48
        int i;
48
        int i;
49
 
49
 
50
        if( (p = (struct node*)malloc(sizeof(struct node))) ){
50
        if( (p = (struct node*)malloc(sizeof(struct node))) ){
51
                #ifdef DEBUG
51
                #ifdef DEBUG
52
                //fprintf(stderr,"NEW(%#x)\n",p);
52
                //fprintf(stderr,"NEW(%#x)\n",p);
53
                ++allocs;
53
                ++allocs;
54
                #endif
54
                #endif
55
                p->kind = k;
55
                p->kind = k;
56
                for( i = 0 ; i < MAXCHILDREN ; ++i )
56
                for( i = 0 ; i < MAXCHILDREN ; ++i )
57
                        p->child[i] = 0;
57
                        p->child[i] = 0;
58
 
58
 
59
                /* add this new node to the list of allocated nodes */
59
                /* add this new node to the list of allocated nodes */
60
                p->next = node_list;
60
                p->next = node_list;
61
                node_list = p;
61
                node_list = p;
62
        }
62
        }
63
        return p;
63
        return p;
64
}
64
}
65
 
65
 
66
void freenodes(struct node *p){
66
void freenodes(struct node *p){
67
        /* undo recorded allocations */
67
        /* undo recorded allocations */
68
        if(p){
68
        if(p){
69
                freenodes(p->next);
69
                freenodes(p->next);
70
                free(p);
70
                free(p);
71
                #ifdef DEBUG
71
                #ifdef DEBUG
72
                //fprintf(stderr,"FREE(%#x)\n",p);
72
                //fprintf(stderr,"FREE(%#x)\n",p);
73
                --allocs;
73
                --allocs;
74
                #endif
74
                #endif
75
        }
75
        }
76
}
76
}
77
void freeallnodes(){
77
void freeallnodes(){
78
        freenodes(node_list);
78
        freenodes(node_list);
79
        node_list = 0;
79
        node_list = 0;
80
}
80
}
81
 
81
 
82
/* pretty-print the tree */
82
/* pretty-print the tree */
83
 
83
 
84
void dumptree(struct node *root,int level){
84
void dumptree(struct node *root,int level){
85
        int i;
85
        int i;
86
 
86
 
87
        if(level>20)
87
        if(level>20)
88
                puts("## dumptree: sorry, not going deeper than this.");
88
                puts("## dumptree: sorry, not going deeper than this.");
89
        else
89
        else
90
                if(root){
90
                if(root){
91
                        for(i=level;i--;)
91
                        for(i=level;i--;)
92
                                putchar('\t');
92
                                putchar('\t');
93
                        switch(root->kind){
93
                        switch(root->kind){
94
                        case TOK_NUM:
94
                        case TOK_NUM:
95
                                #ifdef FP_VALUE
95
                                #ifdef FP_VALUE
96
                                printf("constant: %g\n",root->v.value);
96
                                printf("constant: %g\n",root->v.value);
97
                                #else
97
                                #else
98
                                printf("constant: %ld\n",root->v.value);
98
                                printf("constant: %d\n",root->v.value);
99
                                #endif
99
                                #endif
100
                                break;
100
                                break;
101
                        case TOK_SPECIALVAR:
101
                        case TOK_SPECIALVAR:
102
                                printf("special variable: %c\n",root->v.specialvar);
102
                                printf("special variable: %c\n",root->v.specialvar);
103
                                break;
103
                                break;
104
                        case TOK_VAR:
104
                        case TOK_VAR:
105
                                #ifdef FP_VALUE
105
                                #ifdef FP_VALUE
106
                                printf("variable: %s (%g)\n",root->v.sym->name,*root->v.sym->pvar);
106
                                printf("variable: %s (%g)\n",root->v.sym->name,*root->v.sym->pvar);
107
                                #else
107
                                #else
108
                                printf("variable: %s (%ld)\n",root->v.sym->name,*root->v.sym->pvar);
108
                                printf("variable: %s (%d)\n",root->v.sym->name,*root->v.sym->pvar);
109
                                #endif
109
                                #endif
110
                                break;
110
                                break;
111
                        case TOK_FN1:
111
                        case TOK_FN1:
112
                        case TOK_FN2:
112
                        case TOK_FN2:
113
                        case TOK_FN3:
113
                        case TOK_FN3:
114
                                printf("function: %s\n",root->v.sym->name);
114
                                printf("function: %s\n",root->v.sym->name);
115
                                break;
115
                                break;
116
                        default:
116
                        default:
117
                                printf(isprint(root->kind) ? "operator: %c\n" : "operator: %d\n",root->kind);
117
                                printf(isprint(root->kind) ? "operator: %c\n" : "operator: %d\n",root->kind);
118
                                break;
118
                                break;
119
                        }
119
                        }
120
                        ++level;
120
                        ++level;
121
                        for( i = 0 ; i < MAXCHILDREN ; ++i )
121
                        for( i = 0 ; i < MAXCHILDREN ; ++i )
122
                                dumptree(root->child[i],level);
122
                                dumptree(root->child[i],level);
123
                }
123
                }
124
 
124
 
125
}
125
}
126
 
126
 
127
/* evaluate the expression tree (using current values of variables) */
127
/* evaluate the expression tree (using current values of variables) */
128
 
128
 
129
value_type eval(struct node *root){
129
value_type eval(struct node *root){
130
        value_type t;
130
        value_type t;
131
        if(root){
131
        if(root){
132
                switch(root->kind){
132
                switch(root->kind){
133
                case TOK_NUM: return root->v.value;
133
                case TOK_NUM: return root->v.value;
134
                case TOK_SPECIALVAR: return var[root->v.specialvar];
134
                case TOK_SPECIALVAR: return var[root->v.specialvar];
135
                case TOK_VAR: return *root->v.sym->pvar;
135
                case TOK_VAR: return *root->v.sym->pvar;
136
                case TOK_FN1: return root->v.sym->fn(eval(root->child[0]));
136
                case TOK_FN1: return root->v.sym->fn(eval(root->child[0]));
137
                case TOK_FN2: return root->v.sym->fn(
137
                case TOK_FN2: return root->v.sym->fn(
138
                                                     eval(root->child[0]),
138
                                                     eval(root->child[0]),
139
                                                     eval(root->child[1]) );
139
                                                     eval(root->child[1]) );
140
                case TOK_FN3: return root->v.sym->fn(
140
                case TOK_FN3: return root->v.sym->fn(
141
                                                     eval(root->child[0]),
141
                                                     eval(root->child[0]),
142
                                                     eval(root->child[1]),
142
                                                     eval(root->child[1]),
143
                                                     eval(root->child[2]) );
143
                                                     eval(root->child[2]) );
144
                case TOK_FN4: return root->v.sym->fn(
144
                case TOK_FN4: return root->v.sym->fn(
145
                                                     eval(root->child[0]),
145
                                                     eval(root->child[0]),
146
                                                     eval(root->child[1]),
146
                                                     eval(root->child[1]),
147
                                                     eval(root->child[2]),
147
                                                     eval(root->child[2]),
148
                                                     eval(root->child[3]) );
148
                                                     eval(root->child[3]) );
149
                case TOK_FN5: return root->v.sym->fn(
149
                case TOK_FN5: return root->v.sym->fn(
150
                                                     eval(root->child[0]),
150
                                                     eval(root->child[0]),
151
                                                     eval(root->child[1]),
151
                                                     eval(root->child[1]),
152
                                                     eval(root->child[2]),
152
                                                     eval(root->child[2]),
153
                                                     eval(root->child[3]),
153
                                                     eval(root->child[3]),
154
                                                     eval(root->child[4]) );
154
                                                     eval(root->child[4]) );
155
                case TOK_FN10: return root->v.sym->fn(
155
                case TOK_FN10: return root->v.sym->fn(
156
                                                     eval(root->child[0]),
156
                                                     eval(root->child[0]),
157
                                                     eval(root->child[1]),
157
                                                     eval(root->child[1]),
158
                                                     eval(root->child[2]),
158
                                                     eval(root->child[2]),
159
                                                     eval(root->child[3]),
159
                                                     eval(root->child[3]),
160
                                                     eval(root->child[4]),
160
                                                     eval(root->child[4]),
161
                                                     eval(root->child[5]),
161
                                                     eval(root->child[5]),
162
                                                     eval(root->child[6]),
162
                                                     eval(root->child[6]),
163
                                                     eval(root->child[7]),
163
                                                     eval(root->child[7]),
164
                                                     eval(root->child[8]),
164
                                                     eval(root->child[8]),
165
                                                     eval(root->child[9]) );
165
                                                     eval(root->child[9]) );
166
 
166
 
167
                case '+': return eval(root->child[0]) + eval(root->child[1]);
167
                case '+': return eval(root->child[0]) + eval(root->child[1]);
168
                case '-': return eval(root->child[0]) - eval(root->child[1]);
168
                case '-': return eval(root->child[0]) - eval(root->child[1]);
169
                case '*': return eval(root->child[0]) * eval(root->child[1]);
169
                case '*': return eval(root->child[0]) * eval(root->child[1]);
170
                case '/': t = eval(root->child[1]); return t ? eval(root->child[0]) / t : 0;
170
                case '/': t = eval(root->child[1]); return t ? eval(root->child[0]) / t : 0;
171
                case '%': t = eval(root->child[1]); return t ? eval(root->child[0]) % t : 0;
171
                case '%': t = eval(root->child[1]); return t ? eval(root->child[0]) % t : 0;
172
                case EXP: return (value_type)(pow(eval(root->child[0]), eval(root->child[1])));
172
                case EXP: return (value_type)(pow(eval(root->child[0]), eval(root->child[1])));
173
 
173
 
174
                case EQ:  return eval(root->child[0]) == eval(root->child[1]);
174
                case EQ:  return eval(root->child[0]) == eval(root->child[1]);
175
                case NE:  return eval(root->child[0]) != eval(root->child[1]);
175
                case NE:  return eval(root->child[0]) != eval(root->child[1]);
176
                case '<': return eval(root->child[0]) < eval(root->child[1]);
176
                case '<': return eval(root->child[0]) < eval(root->child[1]);
177
                case LE:  return eval(root->child[0]) <= eval(root->child[1]);
177
                case LE:  return eval(root->child[0]) <= eval(root->child[1]);
178
                case '>': return eval(root->child[0]) > eval(root->child[1]);
178
                case '>': return eval(root->child[0]) > eval(root->child[1]);
179
                case GE:  return eval(root->child[0]) >= eval(root->child[1]);
179
                case GE:  return eval(root->child[0]) >= eval(root->child[1]);
180
 
180
 
181
                case LOGAND: return eval(root->child[0]) && eval(root->child[1]);
181
                case LOGAND: return eval(root->child[0]) && eval(root->child[1]);
182
                case LOGOR:  return eval(root->child[0]) || eval(root->child[1]);
182
                case LOGOR:  return eval(root->child[0]) || eval(root->child[1]);
183
                case '!': return !eval(root->child[0]);
183
                case '!': return !eval(root->child[0]);
184
 
184
 
185
                case '?': return eval(root->child[0]) ? eval(root->child[1]) : eval(root->child[2]);
185
                case '?': return eval(root->child[0]) ? eval(root->child[1]) : eval(root->child[2]);
186
 
186
 
187
                case '&': return eval(root->child[0]) & eval(root->child[1]);
187
                case '&': return eval(root->child[0]) & eval(root->child[1]);
188
                case '^': return eval(root->child[0]) ^ eval(root->child[1]);
188
                case '^': return eval(root->child[0]) ^ eval(root->child[1]);
189
                case '|': return eval(root->child[0]) | eval(root->child[1]);
189
                case '|': return eval(root->child[0]) | eval(root->child[1]);
190
                case SHLEFT:  return eval(root->child[0]) << eval(root->child[1]);
190
                case SHLEFT:  return eval(root->child[0]) << eval(root->child[1]);
191
                case SHRIGHT: return eval(root->child[0]) >> eval(root->child[1]);
191
                case SHRIGHT: return eval(root->child[0]) >> eval(root->child[1]);
192
                case '~': return ~eval(root->child[0]);
192
                case '~': return ~eval(root->child[0]);
193
 
193
 
194
                case ',': eval(root->child[0]); return eval(root->child[1]);
194
                case ',': eval(root->child[0]); return eval(root->child[1]);
195
                }
195
                }
196
        }
196
        }
197
        #ifdef FP_VALUE
197
        #ifdef FP_VALUE
198
        return 0.;
198
        return 0.;
199
        #else
199
        #else
200
        return 0;
200
        return 0;
201
        #endif
201
        #endif
202
}
202
}
203
 
203
 
204
/* free the memory for a tree's nodes */
204
/* free the memory for a tree's nodes */
205
 
205
 
206
void freetree(struct node *root){
206
void freetree(struct node *root){
207
        int i;
207
        int i;
208
 
208
 
209
        if(root){
209
        if(root){
210
                for( i = 0 ; i < MAXCHILDREN ; ++i )
210
                for( i = 0 ; i < MAXCHILDREN ; ++i )
211
                        freetree(root->child[i]);
211
                        freetree(root->child[i]);
212
                free(root);
212
                free(root);
213
        }
213
        }
214
}
214
}
215
 
215
 
216
/* tabulate usage of special variables, or any invocations of src()/rad()/cnv(), in the tree */
216
/* tabulate usage of special variables, or any invocations of src()/rad()/cnv(), in the tree */
217
 
217
 
218
void checkvars(struct node*p,int f[],int *cnv,int *srcrad /* ,int *mapused */, int *state_changing_funcs_used ){
218
void checkvars(struct node*p,int f[],int *cnv,int *srcrad /* ,int *mapused */, int *state_changing_funcs_used ){
219
        int i;
219
        int i;
220
 
220
 
221
        if(p){
221
        if(p){
222
                if(p->kind==TOK_SPECIALVAR)
222
                if(p->kind==TOK_SPECIALVAR)
223
                        f[p->v.specialvar] = 1;
223
                        f[p->v.specialvar] = 1;
224
                else if(p->kind==TOK_FN3 && (p->v.sym->fn == (pfunc_type)ff_src || p->v.sym->fn == (pfunc_type)ff_rad))
224
                else if(p->kind==TOK_FN3 && (p->v.sym->fn == (pfunc_type)ff_src || p->v.sym->fn == (pfunc_type)ff_rad))
225
                        *srcrad = 1;
225
                        *srcrad = 1;
226
                else if(p->kind==TOK_FN10 && p->v.sym->fn == (pfunc_type)ff_cnv)
226
                else if(p->kind==TOK_FN10 && p->v.sym->fn == (pfunc_type)ff_cnv)
227
                        *cnv = 1;
227
                        *cnv = 1;
228
//              else if(p->kind==TOK_FN2 && (p->v.sym->fn == (pfunc_type)ff_map))
228
//              else if(p->kind==TOK_FN2 && (p->v.sym->fn == (pfunc_type)ff_map))
229
//                      *mapused = 1;
229
//                      *mapused = 1;
230
                else if ((p->kind==TOK_FN2 && p->v.sym->fn == (pfunc_type)ff_put) ||
230
                else if ((p->kind==TOK_FN2 && p->v.sym->fn == (pfunc_type)ff_put) ||
231
                         (p->kind==TOK_FN2 && p->v.sym->fn == (pfunc_type)ff_rnd) ||
231
                         (p->kind==TOK_FN2 && p->v.sym->fn == (pfunc_type)ff_rnd) ||
232
                         (p->kind==TOK_FN1 && p->v.sym->fn == (pfunc_type)ff_rst))
232
                         (p->kind==TOK_FN1 && p->v.sym->fn == (pfunc_type)ff_rst))
233
                        *state_changing_funcs_used = 1;
233
                        *state_changing_funcs_used = 1;
234
                for( i = 0 ; i < MAXCHILDREN ; ++i )
234
                for( i = 0 ; i < MAXCHILDREN ; ++i )
235
                        checkvars(p->child[i],f,cnv,srcrad/*,mapused*/,state_changing_funcs_used);
235
                        checkvars(p->child[i],f,cnv,srcrad/*,mapused*/,state_changing_funcs_used);
236
        }
236
        }
237
}
237
}
238
 
238