Subversion Repositories filter_foundry

Rev

Rev 166 | Rev 171 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 toby 1
/*
18 toby 2
    This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
2 toby 3
    Copyright (C) 2003-5 Toby Thain, toby@telegraphics.com.au
4
 
5
    This program is free software; you can redistribute it and/or modify
106 dmarschall 6
    it under the terms of the GNU General Public License as published by
2 toby 7
    the Free Software Foundation; either version 2 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
106 dmarschall 15
    You should have received a copy of the GNU General Public License
2 toby 16
    along with this program; if not, write to the Free Software
17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
*/
19
 
20
#ifdef MAC_ENV
21
        #include <fp.h>
22
#endif
23
 
24
#include <math.h>
25
#include <stdlib.h>
26
 
27
#ifndef PARSERTEST
28
#include "ff.h"
29
#endif
30
#include "funcs.h"
31
#include "y.tab.h"
32
 
117 dmarschall 33
#include "node.h" // for symbol "var[]"
34
 
2 toby 35
#define RINT //no rounding for now
36
 
37
//#if TARGET_API_MAC_CARBON
38
// this is another incompatibility between Classic stdclib and OS X stdclib
39
// ***FIXME: need to access real OS X includes for Carbon build
40
//#undef RAND_MAX
41
//#define RAND_MAX    0x7fffffff
42
//#endif
43
 
44
extern value_type slider[],cell[],var[],map[][0x100];
66 toby 45
extern unsigned char *image_ptr;
2 toby 46
 
135 dmarschall 47
double costab[COSTABSIZE];
48
double tantab[TANTABSIZE];
49
void init_trigtab(){
50
        int i;
51
        for(i=0;i<COSTABSIZE;++i){
52
                costab[i] = cos(FFANGLE(i));
53
        }
54
        for(i=0;i<TANTABSIZE;++i){
136 dmarschall 55
                if (i>=256) {
56
                        /* the last '-1' in the expression '512-i-1' is for FilterFactory compatibility, and to avoid the undefined pi/2 area */
57
                        tantab[i] = -tantab[512-i-1];
58
                } else {
59
                        tantab[i] = tan(FFANGLE(i));
60
                }
135 dmarschall 61
        }
62
}
63
 
71 toby 64
/* Channel z for the input pixel at coordinates x,y.
76 toby 65
 * Coordinates are relative to the input image data (pb->inData) */
79 toby 66
static value_type rawsrc(value_type x,value_type y,value_type z){
106 dmarschall 67
        if(x < gpb->inRect.left)
71 toby 68
                x = gpb->inRect.left;
106 dmarschall 69
        else if(x >= gpb->inRect.right)
71 toby 70
                x = gpb->inRect.right-1;
106 dmarschall 71
        if(y < gpb->inRect.top)
71 toby 72
                y = gpb->inRect.top;
106 dmarschall 73
        else if(y >= gpb->inRect.bottom)
71 toby 74
                y = gpb->inRect.bottom-1;
76 toby 75
        return ((unsigned char*)gpb->inData)[ (long)gpb->inRowBytes*(y - gpb->inRect.top)
76
                                                                                  + (long)nplanes*(x - gpb->inRect.left) + z ];
71 toby 77
}
78
 
79
/* src(x,y,z) Channel z for the pixel at coordinates x,y.
80
 * Coordinates are relative to filtered area (selection). */
81
value_type ff_src(value_type x,value_type y,value_type z){
76 toby 82
#ifdef PARSERTEST
83
        return 0;
84
#else
106 dmarschall 85
        if(x < 0)
2 toby 86
                x = 0;
106 dmarschall 87
        else if(x >= var['X'])
2 toby 88
                x = var['X']-1;
106 dmarschall 89
        if(y < 0)
2 toby 90
                y = 0;
106 dmarschall 91
        else if(y >= var['Y'])
2 toby 92
                y = var['Y']-1;
71 toby 93
        return z >= 0 && z < var['Z'] ?
94
                image_ptr[(long)gpb->inRowBytes*y + (long)nplanes*x + z] : 0;
76 toby 95
#endif
2 toby 96
}
97
 
71 toby 98
/* rad(d,m,z) Channel z in the source image, which is m units away,
99
        at an angle of d, from the center of the image */
2 toby 100
value_type ff_rad(value_type d,value_type m,value_type z){
71 toby 101
        return ff_src(ff_r2x(d,m) + var['X']/2, ff_r2y(d,m) + var['Y']/2, z);
2 toby 102
}
103
 
104
/* ctl(i) Value of slider i, where i is an integer between 0 and 7, inclusive */
105
value_type ff_ctl(value_type i){
106
        return i>=0 && i<=7 ? slider[i] : 0;
107
}
108
 
109
/* val(i,a,b) Value of slider i, mapped onto the range a to b */
110
value_type ff_val(value_type i,value_type a,value_type b){
111
        return ((long)ff_ctl(i)*(b-a))/255 + a;
112
}
113
 
114
/* map(i,n) Item n from mapping table i, where i is an integer between
115
 
116
        inclusive */
117
value_type ff_map(value_type i,value_type n){
118
/*
119
        if( i>=0 && i<=3 && n>=0 && n<=255 ){
120
                int H = slider[i*2],L = slider[i*2+1];
121
                return n<=L || H==L ? 0 : ( n>=H ? 255 : ((n-L)*255L)/(H-L) );
122
        }else
123
                return 0;
124
*/
125
        // this code is from GIMP User Filter
126
        value_type x = ff_ctl(i*2),
127
                           y = ff_ctl(i*2+1);
128
        return abs(((long)n*(y-x) / 255)+x);
129
}
130
 
131
/* min(a,b) Lesser of a and b */
132
value_type ff_min(value_type a,value_type b){
133
        return a < b ? a : b;
134
}
135
 
136
/* max(a,b) Greater of a and b */
137
value_type ff_max(value_type a,value_type b){
138
        return a > b ? a : b;
139
}
140
 
141
/* abs(a) Absolute value of a */
142
value_type ff_abs(value_type a){
143
        return abs(a);
144
}
145
 
146
/* add(a,b,c) Sum of a and b, or c, whichever is lesser */
147
value_type ff_add(value_type a,value_type b,value_type c){
148
        return ff_min(a+b,c);
149
}
150
 
151
/* sub(a,b,c) Difference of a and b, or c, whichever is greater */
152
value_type ff_sub(value_type a,value_type b,value_type c){
153
        return ff_max(ff_dif(a,b),c);
154
}
155
 
156
/* dif(a,b) Absolute value of the difference of a and b */
157
value_type ff_dif(value_type a,value_type b){
158
        return abs(a-b);
159
}
160
 
161
/* rnd(a,b) Random number between a and b, inclusive */
162
value_type ff_rnd(value_type a,value_type b){
163
        return (int)((abs(a-b)+1)*(rand()/(RAND_MAX+1.))) + ff_min(a,b);
164
//      return ((unsigned)rand() % (ff_dif(a,b)+1)) + ff_min(a,b);
165
}
166
 
167
/* mix(a,b,n,d) Mixture of a and b by fraction n/d, a*n/d+b*(d-n)/d */
168
value_type ff_mix(value_type a,value_type b,value_type n,value_type d){
169
        return d ? ((long)a*n)/d + ((long)b*(d-n))/d : 0;
170
}
171
 
172
/* scl(a,il,ih,ol,oh) Scale a from input range (il to ih)
173
                      to output range (ol to oh) */
174
value_type ff_scl(value_type a,value_type il,value_type ih,
141 dmarschall 175
                  value_type ol,value_type oh){
2 toby 176
        return ih==il ? 0 : ol + ((long)(oh-ol)*(a-il))/(ih-il);
177
}
178
 
170 dmarschall 179
inline uint32_t isqrt(uint32_t x) {
180
        // based on https://gist.github.com/orlp/3481770
2 toby 181
 
170 dmarschall 182
        static uint32_t lkpSquares[65535];
183
        static int lkpInitialized = 0;
184
        const uint32_t *p;
185
        int i;
2 toby 186
 
170 dmarschall 187
        while (lkpInitialized == 1) { /* If other thread is currently creating the lookup table, then wait */ }
188
        if (!lkpInitialized) {
189
                lkpInitialized = 1;
190
                for (i = 0; i < 65535; ++i) {
191
                        lkpSquares[i] = i * i;
192
                }
193
                lkpInitialized = 2;
194
        }
2 toby 195
 
170 dmarschall 196
        p = lkpSquares;
2 toby 197
 
170 dmarschall 198
        if (p[32768] <= x) p += 32768;
199
        if (p[16384] <= x) p += 16384;
200
        if (p[8192] <= x) p += 8192;
201
        if (p[4096] <= x) p += 4096;
202
        if (p[2048] <= x) p += 2048;
203
        if (p[1024] <= x) p += 1024;
204
        if (p[512] <= x) p += 512;
205
        if (p[256] <= x) p += 256;
206
        if (p[128] <= x) p += 128;
207
        if (p[64] <= x) p += 64;
208
        if (p[32] <= x) p += 32;
209
        if (p[16] <= x) p += 16;
210
        if (p[8] <= x) p += 8;
211
        if (p[4] <= x) p += 4;
212
        if (p[2] <= x) p += 2;
213
        if (p[1] <= x) p += 1;
2 toby 214
 
170 dmarschall 215
        return p - lkpSquares;
2 toby 216
}
217
 
218
/* sqr(x) Square root of x */
219
value_type ff_sqr(value_type x){
220
        return x < 0 ? 0 : isqrt(x);
221
}
222
 
223
/* sin(x) Sine function of x, where x is an integer between 0 and
141 dmarschall 224
   1024, inclusive, and the value returned is an integer
225
   between -512 and 512, inclusive (Windows) or -1024 and
226
   1024, inclusive (Mac OS) */
2 toby 227
value_type ff_sin(value_type x){
134 dmarschall 228
        //return RINT(TRIGAMP*sin(FFANGLE(x)));
229
        return ff_cos(x-256);
2 toby 230
}
231
 
134 dmarschall 232
/* cos(x) Cosine function of x, where x is an integer between 0 and
233
   1024, inclusive, and the value returned is an integer
234
   between -512 and 512, inclusive (Windows) or -1024 and
235
   1024, inclusive (Mac OS) */
2 toby 236
value_type ff_cos(value_type x){
134 dmarschall 237
        //return RINT(TRIGAMP*cos(FFANGLE(x)));
136 dmarschall 238
        return RINT(TRIGAMP*costab[abs(x) % COSTABSIZE]);
2 toby 239
}
240
 
134 dmarschall 241
/* tan(x) Bounded tangent function of x, where x is an integer
242
   between -256 and 256, inclusive, and the value returned is
243
   an integer between -512 and 512, inclusive (Windows) or
244
   -1024 and 1024, inclusive (Mac OS) */
2 toby 245
value_type ff_tan(value_type x){
134 dmarschall 246
        // TODO: Shouldn't the output be bounded to -1024..1024, or do I understand the definition wrong?
136 dmarschall 247
        if (x < 0) x--; /* required for FilterFactory compatibility */
248
        while (x < 0) x += TANTABSIZE;
249
        return RINT(2*TRIGAMP*tantab[x % TANTABSIZE]); /* FIXME: why do we need factor 2? */
2 toby 250
}
251
 
252
/* r2x(d,m) x displacement of the pixel m units away, at an angle of d,
253
   from an arbitrary center */
254
value_type ff_r2x(value_type d,value_type m){
135 dmarschall 255
        return RINT(m*costab[abs(d) % COSTABSIZE]);
2 toby 256
}
257
 
258
/* r2y(d,m) y displacement of the pixel m units away, at an angle of d,
259
   from an arbitrary center */
260
value_type ff_r2y(value_type d,value_type m){
135 dmarschall 261
        return RINT(m*costab[abs(d-256) % COSTABSIZE]);
2 toby 262
}
263
 
264
/* c2d(x,y) Angle displacement of the pixel at coordinates x,y */
265
/* note, sign of y difference is negated, as we are dealing with top-down coordinates
266
   angle is "observed" */
267
value_type ff_c2d(value_type x,value_type y){
139 dmarschall 268
        // Behavior of FilterFoundry <1.7:
154 dmarschall 269
        //return RINT(TO_FFANGLE(atan2(-y,-x)));
139 dmarschall 270
 
271
        // Behavior in FilterFoundry 1.7+: Matches FilterFactory
272
        return RINT(TO_FFANGLE(atan2(y,x)));
2 toby 273
}
274
 
275
/* c2m(x,y) Magnitude displacement of the pixel at coordinates x,y */
276
value_type ff_c2m(value_type x,value_type y){
277
        return isqrt((long)x*x + (long)y*y);
278
}
279
 
280
/* get(i) Returns the current cell value at i */
281
value_type ff_get(value_type i){
141 dmarschall 282
        // Filter Factory:
142 dmarschall 283
        //return i>=0 && i<NUM_CELLS ? cell[i] : i;
141 dmarschall 284
 
285
        // Filter Foundry:
142 dmarschall 286
        return i>=0 && i<NUM_CELLS ? cell[i] : 0;
2 toby 287
}
288
 
289
/* put(v,i) Puts the new value v into cell i */
290
value_type ff_put(value_type v,value_type i){
142 dmarschall 291
        if(i>=0 && i<NUM_CELLS)
2 toby 292
                cell[i] = v;
293
        return v;
294
}
295
 
296
value_type ff_cnv(value_type m11,value_type m12,value_type m13,
297
                                  value_type m21,value_type m22,value_type m23,
298
                                  value_type m31,value_type m32,value_type m33,
71 toby 299
                                  value_type d)
300
{
76 toby 301
#ifdef PARSERTEST
302
        return 0;
303
#else
71 toby 304
        long total;
305
        // shift x,y from selection-relative to image relative
306
        int x = var['x'] + gpb->filterRect.left,
307
                y = var['y'] + gpb->filterRect.top,
308
                z = var['z'];
2 toby 309
 
71 toby 310
        if(z >= 0 && z < var['Z'])
311
                total = m11*rawsrc(x-1,y-1,z) + m12*rawsrc(x,y-1,z) + m13*rawsrc(x+1,y-1,z)
312
                          + m21*rawsrc(x-1,y,  z) + m22*rawsrc(x,y,  z) + m23*rawsrc(x+1,y,  z)
313
                          + m31*rawsrc(x-1,y+1,z) + m32*rawsrc(x,y+1,z) + m33*rawsrc(x+1,y+1,z);
314
        else
315
                total = 0;
2 toby 316
 
317
        return d ? total/d : 0;
76 toby 318
#endif
2 toby 319
}
320
 
106 dmarschall 321
/* rst(i) sets a random seed and returns 0. (undocumented Filter Factory function).
322
   Added by DM, 18 Dec 2018 */
323
value_type ff_rst(value_type seed){
324
        srand(seed);
325
        return 0;
326
}
327
 
2 toby 328
value_type zero_val = 0;
118 dmarschall 329
value_type one_val = 1;
117 dmarschall 330
value_type max_channel_val = 255;
2 toby 331
 
332
/* predefined symbols */
333
struct sym_rec predefs[]={
334
        /* functions */
117 dmarschall 335
 
2 toby 336
        {0,TOK_FN3,"src", (pfunc_type)ff_src, 0},
337
        {0,TOK_FN3,"rad", (pfunc_type)ff_rad, 0},
338
        {0,TOK_FN1,"ctl", (pfunc_type)ff_ctl, 0},
339
        {0,TOK_FN3,"val", (pfunc_type)ff_val, 0},
340
        {0,TOK_FN2,"map", (pfunc_type)ff_map, 0},
341
        {0,TOK_FN2,"min", (pfunc_type)ff_min, 0},
342
        {0,TOK_FN2,"max", (pfunc_type)ff_max, 0},
343
        {0,TOK_FN1,"abs", (pfunc_type)ff_abs, 0},
344
        {0,TOK_FN3,"add", (pfunc_type)ff_add, 0},
345
        {0,TOK_FN3,"sub", (pfunc_type)ff_sub, 0},
346
        {0,TOK_FN2,"dif", (pfunc_type)ff_dif, 0},
347
        {0,TOK_FN2,"rnd", (pfunc_type)ff_rnd, 0},
348
        {0,TOK_FN4,"mix", (pfunc_type)ff_mix, 0},
349
        {0,TOK_FN5,"scl", (pfunc_type)ff_scl, 0},
350
        {0,TOK_FN1,"sqr", (pfunc_type)ff_sqr, 0},
146 dmarschall 351
        {0,TOK_FN1,"sqrt", (pfunc_type)ff_sqr, 0}, // sqrt() is synonym to sqr() in Premiere
2 toby 352
        {0,TOK_FN1,"sin", (pfunc_type)ff_sin, 0},
353
        {0,TOK_FN1,"cos", (pfunc_type)ff_cos, 0},
354
        {0,TOK_FN1,"tan", (pfunc_type)ff_tan, 0},
355
        {0,TOK_FN2,"r2x", (pfunc_type)ff_r2x, 0},
356
        {0,TOK_FN2,"r2y", (pfunc_type)ff_r2y, 0},
357
        {0,TOK_FN2,"c2d", (pfunc_type)ff_c2d, 0},
358
        {0,TOK_FN2,"c2m", (pfunc_type)ff_c2m, 0},
359
        {0,TOK_FN1,"get", (pfunc_type)ff_get, 0},
360
        {0,TOK_FN2,"put", (pfunc_type)ff_put, 0},
361
        {0,TOK_FN10,"cnv",(pfunc_type)ff_cnv, 0},
117 dmarschall 362
        {0,TOK_FN1,"rst", (pfunc_type)ff_rst, 0}, // undocumented FilterFactory function
363
 
364
        /* predefined variables (names with more than 1 character); most of them are undocumented in FilterFactory */
365
        /* the predefined variables with 1 character are defined in lexer.l and process.c */
366
        /* in this table, you must not add TOK_VAR with only 1 character (since this case is not defined in parser.y) */
367
 
368
        {0,TOK_VAR,"rmax",0, &max_channel_val}, // alias of 'R' (defined in lexer.l, line 129)
369
        {0,TOK_VAR,"gmax",0, &max_channel_val}, // alias of 'G' (defined in lexer.l, line 129)
370
        {0,TOK_VAR,"bmax",0, &max_channel_val}, // alias of 'B' (defined in lexer.l, line 129)
371
        {0,TOK_VAR,"amax",0, &max_channel_val}, // alias of 'A' (defined in lexer.l, line 129)
372
        {0,TOK_VAR,"cmax",0, &max_channel_val}, // alias of 'C' (defined in lexer.l, line 129)
373
        {0,TOK_VAR,"imax",0, &max_channel_val}, // alias of 'I' (defined in lexer.l, line 129)
374
        {0,TOK_VAR,"umax",0, &max_channel_val}, // alias of 'U' (defined in lexer.l, line 129)
375
        {0,TOK_VAR,"vmax",0, &max_channel_val}, // alias of 'V' (defined in lexer.l, line 129)
376
        {0,TOK_VAR,"dmax",0, &var['D']},
377
        {0,TOK_VAR,"mmax",0, &var['M']},
378
        {0,TOK_VAR,"pmax",0, &var['Z']},
379
        {0,TOK_VAR,"xmax",0, &var['X']},
380
        {0,TOK_VAR,"ymax",0, &var['Y']},
381
        {0,TOK_VAR,"zmax",0, &var['Z']},
382
 
383
        {0,TOK_VAR,"rmin",0, &zero_val},
384
        {0,TOK_VAR,"gmin",0, &zero_val},
385
        {0,TOK_VAR,"bmin",0, &zero_val},
386
        {0,TOK_VAR,"amin",0, &zero_val},
387
        {0,TOK_VAR,"cmin",0, &zero_val},
388
        {0,TOK_VAR,"imin",0, &zero_val},
389
        {0,TOK_VAR,"umin",0, &zero_val},
390
        {0,TOK_VAR,"vmin",0, &zero_val},
2 toby 391
        {0,TOK_VAR,"dmin",0, &zero_val},
392
        {0,TOK_VAR,"mmin",0, &zero_val},
117 dmarschall 393
        {0,TOK_VAR,"pmin",0, &zero_val},
394
        {0,TOK_VAR,"xmin",0, &zero_val},
395
        {0,TOK_VAR,"ymin",0, &zero_val},
396
        {0,TOK_VAR,"zmin",0, &zero_val},
397
 
398
        /* Undocumented synonyms of FilterFactory for compatibility with Premiere */
399
        {0,TOK_FN10,"cnv0",(pfunc_type)ff_cnv, 0},
400
        {0,TOK_FN3,"src0", (pfunc_type)ff_src, 0},
401
        {0,TOK_FN3,"rad0", (pfunc_type)ff_rad, 0},
402
        {0,TOK_FN10,"cnv1",(pfunc_type)ff_cnv, 0},
403
        {0,TOK_FN3,"src1", (pfunc_type)ff_src, 0},
404
        {0,TOK_FN3,"rad1", (pfunc_type)ff_rad, 0},
405
        {0,TOK_VAR,"r0",0, &var['r']},
406
        {0,TOK_VAR,"g0",0, &var['g']},
407
        {0,TOK_VAR,"b0",0, &var['b']},
408
        {0,TOK_VAR,"a0",0, &var['a']},
409
        {0,TOK_VAR,"c0",0, &var['c']},
410
        {0,TOK_VAR,"i0",0, &var['i']},
411
        {0,TOK_VAR,"u0",0, &var['u']},
412
        {0,TOK_VAR,"v0",0, &var['v']},
413
        {0,TOK_VAR,"d0",0, &var['d']},
414
        {0,TOK_VAR,"m0",0, &var['m']},
415
        {0,TOK_VAR,"r1",0, &var['r']},
416
        {0,TOK_VAR,"g1",0, &var['g']},
417
        {0,TOK_VAR,"b1",0, &var['b']},
418
        {0,TOK_VAR,"a1",0, &var['a']},
419
        {0,TOK_VAR,"c1",0, &var['c']},
420
        {0,TOK_VAR,"i1",0, &var['i']},
421
        {0,TOK_VAR,"u1",0, &var['u']},
422
        {0,TOK_VAR,"v1",0, &var['v']},
423
        {0,TOK_VAR,"d1",0, &var['d']},
424
        {0,TOK_VAR,"m1",0, &var['m']},
425
        {0,TOK_VAR,"tmin",0, &zero_val},
426
        {0,TOK_VAR,"tmax",0, &one_val},
427
        {0,TOK_VAR,"total",0, &one_val},
428
 
2 toby 429
        {0,0,0,0,0}
117 dmarschall 430
};