Subversion Repositories filter_foundry

Rev

Rev 18 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 toby 1
/*
2
        This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
3
        plugin for Adobe Photoshop
4
    Copyright (C) 2003-5 Toby Thain, toby@telegraphics.com.au
5
 
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  
8
    the Free Software Foundation; either version 2 of the License, or
9
    (at your option) any later version.
10
 
11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
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
18
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
*/
20
 
21
#ifdef MAC_ENV
22
        #include <fp.h>
23
#endif
24
 
25
#include <math.h>
26
#include <stdlib.h>
27
 
28
#ifndef PARSERTEST
29
#include "ff.h"
30
#endif
31
#include "funcs.h"
32
#include "y.tab.h"
33
 
34
#define RINT //no rounding for now
35
 
36
//#if TARGET_API_MAC_CARBON
37
// this is another incompatibility between Classic stdclib and OS X stdclib
38
// ***FIXME: need to access real OS X includes for Carbon build
39
//#undef RAND_MAX
40
//#define RAND_MAX    0x7fffffff
41
//#endif
42
 
43
extern value_type slider[],cell[],var[],map[][0x100];
44
 
45
/* src(x,y,z) Channel z for the pixel at coordinates x,y */
46
value_type ff_src(value_type x,value_type y,value_type z){
47
#ifdef PARSERTEST
48
        return 0;
49
#else
50
        if(x<0)
51
                x = 0;
52
        else if(x>=var['X'])
53
                x = var['X']-1;
54
        if(y<0)
55
                y = 0;
56
        else if(y>=var['Y'])
57
                y = var['Y']-1;
58
        return z>=0 && z<var['Z'] ? ((unsigned char*)gpb->inData)[ (long)gpb->inRowBytes*y + (long)nplanes*x + z ] : 0;
59
#endif
60
}
61
 
62
/* rad(d,m,z) Channel z in the source image, which is m units away, at an
63
        angle of d, from the center of the image */
64
value_type ff_rad(value_type d,value_type m,value_type z){
65
        return ff_src(ff_r2x(d,m)+var['X']/2,ff_r2y(d,m)+var['Y']/2,z);
66
}
67
 
68
/* ctl(i) Value of slider i, where i is an integer between 0 and 7, inclusive */
69
value_type ff_ctl(value_type i){
70
        return i>=0 && i<=7 ? slider[i] : 0;
71
}
72
 
73
/* val(i,a,b) Value of slider i, mapped onto the range a to b */
74
value_type ff_val(value_type i,value_type a,value_type b){
75
        return ((long)ff_ctl(i)*(b-a))/255 + a;
76
}
77
 
78
/* map(i,n) Item n from mapping table i, where i is an integer between
79
 
80
        inclusive */
81
value_type ff_map(value_type i,value_type n){
82
/*
83
        if( i>=0 && i<=3 && n>=0 && n<=255 ){
84
                int H = slider[i*2],L = slider[i*2+1];
85
                return n<=L || H==L ? 0 : ( n>=H ? 255 : ((n-L)*255L)/(H-L) );
86
        }else
87
                return 0;
88
*/
89
        // this code is from GIMP User Filter
90
        value_type x = ff_ctl(i*2),
91
                           y = ff_ctl(i*2+1);
92
        return abs(((long)n*(y-x) / 255)+x);
93
}
94
 
95
/* min(a,b) Lesser of a and b */
96
value_type ff_min(value_type a,value_type b){
97
        return a < b ? a : b;
98
}
99
 
100
/* max(a,b) Greater of a and b */
101
value_type ff_max(value_type a,value_type b){
102
        return a > b ? a : b;
103
}
104
 
105
/* abs(a) Absolute value of a */
106
value_type ff_abs(value_type a){
107
        return abs(a);
108
}
109
 
110
/* add(a,b,c) Sum of a and b, or c, whichever is lesser */
111
value_type ff_add(value_type a,value_type b,value_type c){
112
        return ff_min(a+b,c);
113
}
114
 
115
/* sub(a,b,c) Difference of a and b, or c, whichever is greater */
116
value_type ff_sub(value_type a,value_type b,value_type c){
117
        return ff_max(ff_dif(a,b),c);
118
}
119
 
120
/* dif(a,b) Absolute value of the difference of a and b */
121
value_type ff_dif(value_type a,value_type b){
122
        return abs(a-b);
123
}
124
 
125
/* rnd(a,b) Random number between a and b, inclusive */
126
value_type ff_rnd(value_type a,value_type b){
127
        return (int)((abs(a-b)+1)*(rand()/(RAND_MAX+1.))) + ff_min(a,b);
128
//      return ((unsigned)rand() % (ff_dif(a,b)+1)) + ff_min(a,b);
129
}
130
 
131
/* mix(a,b,n,d) Mixture of a and b by fraction n/d, a*n/d+b*(d-n)/d */
132
value_type ff_mix(value_type a,value_type b,value_type n,value_type d){
133
        return d ? ((long)a*n)/d + ((long)b*(d-n))/d : 0;
134
}
135
 
136
/* scl(a,il,ih,ol,oh) Scale a from input range (il to ih)
137
                      to output range (ol to oh) */
138
value_type ff_scl(value_type a,value_type il,value_type ih,
139
                                  value_type ol,value_type oh){
140
        return ih==il ? 0 : ol + ((long)(oh-ol)*(a-il))/(ih-il);
141
}
142
 
143
/* adapted from http://remus.rutgers.edu/~rhoads/Code/isqrt.c */
144
/* also see http://www.freaknet.org/martin/tape/gos/misc/personal/msc/sqrt/sqrt.c */
145
#define NBITS (sizeof(long)*8)
146
#define TOP2BITS(x) (x>>(NBITS-2))
147
 
148
unsigned long isqrt (unsigned long x)
149
{
150
    int i;
151
    unsigned long a = 0, e = 0, r = 0;
152
 
153
 
154
    for (i=0; i < (NBITS >> 1); i++)
155
        {
156
        r <<= 2;
157
        r +=  TOP2BITS(x);
158
        x <<= 2;
159
 
160
        a <<= 1;
161
        e  =  (a<<1) | 1;
162
 
163
        if (r >= e)
164
            {
165
            r -= e;
166
            a++;
167
            }
168
        }
169
 
170
    return a;
171
}
172
 
173
/* sqr(x) Square root of x */
174
value_type ff_sqr(value_type x){
175
        return x < 0 ? 0 : isqrt(x);
176
}
177
 
178
/* sin(x) Sine function of x, where x is an integer between 0 and
179
        1024, inclusive, and the value returned is an integer
180
        between -512 and 512, inclusive (Windows) or -1024 and
181
        1024, inclusive (Mac OS) */
182
value_type ff_sin(value_type x){
183
        return ff_cos(x-256); //RINT(TRIGAMP*sin(FFANGLE(x)));
184
}
185
 
186
/* cos(x) Cosine function of x */
187
value_type ff_cos(value_type x){
188
        return costab[abs(x) % COSTABSIZE]; //RINT(TRIGAMP*cos(FFANGLE(x)));
189
}
190
 
191
/* tan(x)
192
        Bounded tangent function of x, where x is an integer
193
        between -256 and 256, inclusive, and the value returned is
194
         */
195
value_type ff_tan(value_type x){
196
        return tantab[(x+256) % TANTABSIZE]; //RINT(TRIGAMP*tan(FFANGLE(x)));
197
}
198
 
199
/* r2x(d,m) x displacement of the pixel m units away, at an angle of d,
200
   from an arbitrary center */
201
value_type ff_r2x(value_type d,value_type m){
202
        return RINT(m*cos(FFANGLE(d)));
203
}
204
 
205
/* r2y(d,m) y displacement of the pixel m units away, at an angle of d,
206
   from an arbitrary center */
207
value_type ff_r2y(value_type d,value_type m){
208
        return RINT(m*sin(FFANGLE(d)));
209
}
210
 
211
/* c2d(x,y) Angle displacement of the pixel at coordinates x,y */
212
/* note, sign of y difference is negated, as we are dealing with top-down coordinates
213
   angle is "observed" */
214
value_type ff_c2d(value_type x,value_type y){
215
        return RINT(TO_FFANGLE(atan2(-y,-x))); /* FIXME: why must we negate x here? */
216
}
217
 
218
/* c2m(x,y) Magnitude displacement of the pixel at coordinates x,y */
219
value_type ff_c2m(value_type x,value_type y){
220
        return isqrt((long)x*x + (long)y*y);
221
}
222
 
223
/* get(i) Returns the current cell value at i */
224
value_type ff_get(value_type i){
225
        return i>=0 && i<=0xff ? cell[i] : 0;
226
}
227
 
228
/* put(v,i) Puts the new value v into cell i */
229
value_type ff_put(value_type v,value_type i){
230
        if(i>=0 && i<=0xff)
231
                cell[i] = v;
232
        return v;
233
}
234
 
235
value_type ff_cnv(value_type m11,value_type m12,value_type m13,
236
                                  value_type m21,value_type m22,value_type m23,
237
                                  value_type m31,value_type m32,value_type m33,
238
                                  value_type d ){
239
        long total = 0;
240
        int x=var['x'],y=var['y'];
241
        unsigned char *p = (unsigned char*)gpb->inData + y*(long)gpb->inRowBytes + (x-1)*(long)nplanes + var['z'];
242
 
243
        /* left column */
244
        if(x > 0){
245
                if(y > 0) total += m11*p[ -gpb->inRowBytes ];
246
                total += m21*p[ 0 ];
247
                if(y < var['Y']-1) total += m31*p[ gpb->inRowBytes ];
248
        }
249
 
250
        /* centre column */
251
        p += nplanes;
252
        if(y > 0) total += m12*p[ -gpb->inRowBytes ];
253
        total += m22*p[ 0 ];
254
        if(y < var['Y']-1) total += m32*p[ gpb->inRowBytes ];
255
 
256
        /* right column */
257
        if(x < var['X']-1){
258
                p += nplanes;
259
                if(y > 0) total += m13*p[ -gpb->inRowBytes ];
260
                total += m23*p[ 0 ];
261
                if(y < var['Y']-1) total += m33*p[ gpb->inRowBytes ];
262
        }
263
 
264
        return d ? total/d : 0;
265
}
266
 
267
value_type zero_val = 0;
268
 
269
/* predefined symbols */
270
struct sym_rec predefs[]={
271
        /* functions */
272
        {0,TOK_FN3,"src", (pfunc_type)ff_src, 0},
273
        {0,TOK_FN3,"rad", (pfunc_type)ff_rad, 0},
274
        {0,TOK_FN1,"ctl", (pfunc_type)ff_ctl, 0},
275
        {0,TOK_FN3,"val", (pfunc_type)ff_val, 0},
276
        {0,TOK_FN2,"map", (pfunc_type)ff_map, 0},
277
        {0,TOK_FN2,"min", (pfunc_type)ff_min, 0},
278
        {0,TOK_FN2,"max", (pfunc_type)ff_max, 0},
279
        {0,TOK_FN1,"abs", (pfunc_type)ff_abs, 0},
280
        {0,TOK_FN3,"add", (pfunc_type)ff_add, 0},
281
        {0,TOK_FN3,"sub", (pfunc_type)ff_sub, 0},
282
        {0,TOK_FN2,"dif", (pfunc_type)ff_dif, 0},
283
        {0,TOK_FN2,"rnd", (pfunc_type)ff_rnd, 0},
284
        {0,TOK_FN4,"mix", (pfunc_type)ff_mix, 0},
285
        {0,TOK_FN5,"scl", (pfunc_type)ff_scl, 0},
286
        {0,TOK_FN1,"sqr", (pfunc_type)ff_sqr, 0},
287
        {0,TOK_FN1,"sin", (pfunc_type)ff_sin, 0},
288
        {0,TOK_FN1,"cos", (pfunc_type)ff_cos, 0},
289
        {0,TOK_FN1,"tan", (pfunc_type)ff_tan, 0},
290
        {0,TOK_FN2,"r2x", (pfunc_type)ff_r2x, 0},
291
        {0,TOK_FN2,"r2y", (pfunc_type)ff_r2y, 0},
292
        {0,TOK_FN2,"c2d", (pfunc_type)ff_c2d, 0},
293
        {0,TOK_FN2,"c2m", (pfunc_type)ff_c2m, 0},
294
        {0,TOK_FN1,"get", (pfunc_type)ff_get, 0},
295
        {0,TOK_FN2,"put", (pfunc_type)ff_put, 0},
296
        {0,TOK_FN10,"cnv",(pfunc_type)ff_cnv, 0},
297
        /* predefined variables (names >1 characters) */
298
        {0,TOK_VAR,"dmin",0, &zero_val},
299
        {0,TOK_VAR,"mmin",0, &zero_val},
300
        {0,0,0,0,0}
301
};
302