Subversion Repositories filter_foundry

Rev

Rev 79 | Rev 117 | 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
 
33
#define RINT //no rounding for now
34
 
35
//#if TARGET_API_MAC_CARBON
36
// this is another incompatibility between Classic stdclib and OS X stdclib
37
// ***FIXME: need to access real OS X includes for Carbon build
38
//#undef RAND_MAX
39
//#define RAND_MAX    0x7fffffff
40
//#endif
41
 
42
extern value_type slider[],cell[],var[],map[][0x100];
66 toby 43
extern unsigned char *image_ptr;
2 toby 44
 
71 toby 45
/* Channel z for the input pixel at coordinates x,y.
76 toby 46
 * Coordinates are relative to the input image data (pb->inData) */
79 toby 47
static value_type rawsrc(value_type x,value_type y,value_type z){
106 dmarschall 48
        if(x < gpb->inRect.left)
71 toby 49
                x = gpb->inRect.left;
106 dmarschall 50
        else if(x >= gpb->inRect.right)
71 toby 51
                x = gpb->inRect.right-1;
106 dmarschall 52
        if(y < gpb->inRect.top)
71 toby 53
                y = gpb->inRect.top;
106 dmarschall 54
        else if(y >= gpb->inRect.bottom)
71 toby 55
                y = gpb->inRect.bottom-1;
76 toby 56
        return ((unsigned char*)gpb->inData)[ (long)gpb->inRowBytes*(y - gpb->inRect.top)
57
                                                                                  + (long)nplanes*(x - gpb->inRect.left) + z ];
71 toby 58
}
59
 
60
/* src(x,y,z) Channel z for the pixel at coordinates x,y.
61
 * Coordinates are relative to filtered area (selection). */
62
value_type ff_src(value_type x,value_type y,value_type z){
76 toby 63
#ifdef PARSERTEST
64
        return 0;
65
#else
106 dmarschall 66
        if(x < 0)
2 toby 67
                x = 0;
106 dmarschall 68
        else if(x >= var['X'])
2 toby 69
                x = var['X']-1;
106 dmarschall 70
        if(y < 0)
2 toby 71
                y = 0;
106 dmarschall 72
        else if(y >= var['Y'])
2 toby 73
                y = var['Y']-1;
71 toby 74
        return z >= 0 && z < var['Z'] ?
75
                image_ptr[(long)gpb->inRowBytes*y + (long)nplanes*x + z] : 0;
76 toby 76
#endif
2 toby 77
}
78
 
71 toby 79
/* rad(d,m,z) Channel z in the source image, which is m units away,
80
        at an angle of d, from the center of the image */
2 toby 81
value_type ff_rad(value_type d,value_type m,value_type z){
71 toby 82
        return ff_src(ff_r2x(d,m) + var['X']/2, ff_r2y(d,m) + var['Y']/2, z);
2 toby 83
}
84
 
85
/* ctl(i) Value of slider i, where i is an integer between 0 and 7, inclusive */
86
value_type ff_ctl(value_type i){
87
        return i>=0 && i<=7 ? slider[i] : 0;
88
}
89
 
90
/* val(i,a,b) Value of slider i, mapped onto the range a to b */
91
value_type ff_val(value_type i,value_type a,value_type b){
92
        return ((long)ff_ctl(i)*(b-a))/255 + a;
93
}
94
 
95
/* map(i,n) Item n from mapping table i, where i is an integer between
96
 
97
        inclusive */
98
value_type ff_map(value_type i,value_type n){
99
/*
100
        if( i>=0 && i<=3 && n>=0 && n<=255 ){
101
                int H = slider[i*2],L = slider[i*2+1];
102
                return n<=L || H==L ? 0 : ( n>=H ? 255 : ((n-L)*255L)/(H-L) );
103
        }else
104
                return 0;
105
*/
106
        // this code is from GIMP User Filter
107
        value_type x = ff_ctl(i*2),
108
                           y = ff_ctl(i*2+1);
109
        return abs(((long)n*(y-x) / 255)+x);
110
}
111
 
112
/* min(a,b) Lesser of a and b */
113
value_type ff_min(value_type a,value_type b){
114
        return a < b ? a : b;
115
}
116
 
117
/* max(a,b) Greater of a and b */
118
value_type ff_max(value_type a,value_type b){
119
        return a > b ? a : b;
120
}
121
 
122
/* abs(a) Absolute value of a */
123
value_type ff_abs(value_type a){
124
        return abs(a);
125
}
126
 
127
/* add(a,b,c) Sum of a and b, or c, whichever is lesser */
128
value_type ff_add(value_type a,value_type b,value_type c){
129
        return ff_min(a+b,c);
130
}
131
 
132
/* sub(a,b,c) Difference of a and b, or c, whichever is greater */
133
value_type ff_sub(value_type a,value_type b,value_type c){
134
        return ff_max(ff_dif(a,b),c);
135
}
136
 
137
/* dif(a,b) Absolute value of the difference of a and b */
138
value_type ff_dif(value_type a,value_type b){
139
        return abs(a-b);
140
}
141
 
142
/* rnd(a,b) Random number between a and b, inclusive */
143
value_type ff_rnd(value_type a,value_type b){
144
        return (int)((abs(a-b)+1)*(rand()/(RAND_MAX+1.))) + ff_min(a,b);
145
//      return ((unsigned)rand() % (ff_dif(a,b)+1)) + ff_min(a,b);
146
}
147
 
148
/* mix(a,b,n,d) Mixture of a and b by fraction n/d, a*n/d+b*(d-n)/d */
149
value_type ff_mix(value_type a,value_type b,value_type n,value_type d){
150
        return d ? ((long)a*n)/d + ((long)b*(d-n))/d : 0;
151
}
152
 
153
/* scl(a,il,ih,ol,oh) Scale a from input range (il to ih)
154
                      to output range (ol to oh) */
155
value_type ff_scl(value_type a,value_type il,value_type ih,
156
                                  value_type ol,value_type oh){
157
        return ih==il ? 0 : ol + ((long)(oh-ol)*(a-il))/(ih-il);
158
}
159
 
160
/* adapted from http://remus.rutgers.edu/~rhoads/Code/isqrt.c */
161
/* also see http://www.freaknet.org/martin/tape/gos/misc/personal/msc/sqrt/sqrt.c */
162
#define NBITS (sizeof(long)*8)
163
#define TOP2BITS(x) (x>>(NBITS-2))
164
 
165
unsigned long isqrt (unsigned long x)
166
{
23 toby 167
    unsigned i;
2 toby 168
    unsigned long a = 0, e = 0, r = 0;
169
 
170
 
171
    for (i=0; i < (NBITS >> 1); i++)
172
        {
173
        r <<= 2;
174
        r +=  TOP2BITS(x);
175
        x <<= 2;
176
 
177
        a <<= 1;
178
        e  =  (a<<1) | 1;
179
 
180
        if (r >= e)
181
            {
182
            r -= e;
183
            a++;
184
            }
185
        }
186
 
187
    return a;
188
}
189
 
190
/* sqr(x) Square root of x */
191
value_type ff_sqr(value_type x){
192
        return x < 0 ? 0 : isqrt(x);
193
}
194
 
195
/* sin(x) Sine function of x, where x is an integer between 0 and
196
        1024, inclusive, and the value returned is an integer
197
        between -512 and 512, inclusive (Windows) or -1024 and
198
        1024, inclusive (Mac OS) */
199
value_type ff_sin(value_type x){
200
        return ff_cos(x-256); //RINT(TRIGAMP*sin(FFANGLE(x)));
201
}
202
 
203
/* cos(x) Cosine function of x */
204
value_type ff_cos(value_type x){
205
        return costab[abs(x) % COSTABSIZE]; //RINT(TRIGAMP*cos(FFANGLE(x)));
206
}
207
 
208
/* tan(x)
209
        Bounded tangent function of x, where x is an integer
210
        between -256 and 256, inclusive, and the value returned is
211
         */
212
value_type ff_tan(value_type x){
213
        return tantab[(x+256) % TANTABSIZE]; //RINT(TRIGAMP*tan(FFANGLE(x)));
214
}
215
 
216
/* r2x(d,m) x displacement of the pixel m units away, at an angle of d,
217
   from an arbitrary center */
218
value_type ff_r2x(value_type d,value_type m){
219
        return RINT(m*cos(FFANGLE(d)));
220
}
221
 
222
/* r2y(d,m) y displacement of the pixel m units away, at an angle of d,
223
   from an arbitrary center */
224
value_type ff_r2y(value_type d,value_type m){
225
        return RINT(m*sin(FFANGLE(d)));
226
}
227
 
228
/* c2d(x,y) Angle displacement of the pixel at coordinates x,y */
229
/* note, sign of y difference is negated, as we are dealing with top-down coordinates
230
   angle is "observed" */
231
value_type ff_c2d(value_type x,value_type y){
232
        return RINT(TO_FFANGLE(atan2(-y,-x))); /* FIXME: why must we negate x here? */
233
}
234
 
235
/* c2m(x,y) Magnitude displacement of the pixel at coordinates x,y */
236
value_type ff_c2m(value_type x,value_type y){
237
        return isqrt((long)x*x + (long)y*y);
238
}
239
 
240
/* get(i) Returns the current cell value at i */
241
value_type ff_get(value_type i){
242
        return i>=0 && i<=0xff ? cell[i] : 0;
243
}
244
 
245
/* put(v,i) Puts the new value v into cell i */
246
value_type ff_put(value_type v,value_type i){
247
        if(i>=0 && i<=0xff)
248
                cell[i] = v;
249
        return v;
250
}
251
 
252
value_type ff_cnv(value_type m11,value_type m12,value_type m13,
253
                                  value_type m21,value_type m22,value_type m23,
254
                                  value_type m31,value_type m32,value_type m33,
71 toby 255
                                  value_type d)
256
{
76 toby 257
#ifdef PARSERTEST
258
        return 0;
259
#else
71 toby 260
        long total;
261
        // shift x,y from selection-relative to image relative
262
        int x = var['x'] + gpb->filterRect.left,
263
                y = var['y'] + gpb->filterRect.top,
264
                z = var['z'];
2 toby 265
 
71 toby 266
        if(z >= 0 && z < var['Z'])
267
                total = m11*rawsrc(x-1,y-1,z) + m12*rawsrc(x,y-1,z) + m13*rawsrc(x+1,y-1,z)
268
                          + m21*rawsrc(x-1,y,  z) + m22*rawsrc(x,y,  z) + m23*rawsrc(x+1,y,  z)
269
                          + m31*rawsrc(x-1,y+1,z) + m32*rawsrc(x,y+1,z) + m33*rawsrc(x+1,y+1,z);
270
        else
271
                total = 0;
2 toby 272
 
273
        return d ? total/d : 0;
76 toby 274
#endif
2 toby 275
}
276
 
106 dmarschall 277
/* rst(i) sets a random seed and returns 0. (undocumented Filter Factory function).
278
   Added by DM, 18 Dec 2018 */
279
value_type ff_rst(value_type seed){
280
        srand(seed);
281
        return 0;
282
}
283
 
2 toby 284
value_type zero_val = 0;
285
 
286
/* predefined symbols */
287
struct sym_rec predefs[]={
288
        /* functions */
289
        {0,TOK_FN3,"src", (pfunc_type)ff_src, 0},
290
        {0,TOK_FN3,"rad", (pfunc_type)ff_rad, 0},
291
        {0,TOK_FN1,"ctl", (pfunc_type)ff_ctl, 0},
292
        {0,TOK_FN3,"val", (pfunc_type)ff_val, 0},
293
        {0,TOK_FN2,"map", (pfunc_type)ff_map, 0},
294
        {0,TOK_FN2,"min", (pfunc_type)ff_min, 0},
295
        {0,TOK_FN2,"max", (pfunc_type)ff_max, 0},
296
        {0,TOK_FN1,"abs", (pfunc_type)ff_abs, 0},
297
        {0,TOK_FN3,"add", (pfunc_type)ff_add, 0},
298
        {0,TOK_FN3,"sub", (pfunc_type)ff_sub, 0},
299
        {0,TOK_FN2,"dif", (pfunc_type)ff_dif, 0},
300
        {0,TOK_FN2,"rnd", (pfunc_type)ff_rnd, 0},
301
        {0,TOK_FN4,"mix", (pfunc_type)ff_mix, 0},
302
        {0,TOK_FN5,"scl", (pfunc_type)ff_scl, 0},
303
        {0,TOK_FN1,"sqr", (pfunc_type)ff_sqr, 0},
304
        {0,TOK_FN1,"sin", (pfunc_type)ff_sin, 0},
305
        {0,TOK_FN1,"cos", (pfunc_type)ff_cos, 0},
306
        {0,TOK_FN1,"tan", (pfunc_type)ff_tan, 0},
307
        {0,TOK_FN2,"r2x", (pfunc_type)ff_r2x, 0},
308
        {0,TOK_FN2,"r2y", (pfunc_type)ff_r2y, 0},
309
        {0,TOK_FN2,"c2d", (pfunc_type)ff_c2d, 0},
310
        {0,TOK_FN2,"c2m", (pfunc_type)ff_c2m, 0},
311
        {0,TOK_FN1,"get", (pfunc_type)ff_get, 0},
312
        {0,TOK_FN2,"put", (pfunc_type)ff_put, 0},
313
        {0,TOK_FN10,"cnv",(pfunc_type)ff_cnv, 0},
106 dmarschall 314
        {0,TOK_FN1,"rst", (pfunc_type)ff_rst, 0},
2 toby 315
        /* predefined variables (names >1 characters) */
316
        {0,TOK_VAR,"dmin",0, &zero_val},
317
        {0,TOK_VAR,"mmin",0, &zero_val},
318
        {0,0,0,0,0}
319
};
320