Subversion Repositories filter_foundry

Rev

Rev 2 | Rev 18 | Go to most recent revision | Details | Compare with Previous | 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
    Copyright (C) 2003-5 Toby Thain, toby@telegraphics.com.au
4
 
5
    This program is free software; you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by  
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
 
15
    You should have received a copy of the GNU General Public License  
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
#include "ff.h"
21
#include "symtab.h"
22
#include "node.h"
23
#include "funcs.h"
8 toby 24
#include "y.tab.h"
2 toby 25
 
26
extern value_type var[];
27
extern int nplanes,varused[],srcradused;
28
extern struct node *tree[];
29
int needinput;
30
 
31
/* get prepared to evaluate expression trees--
32
   this assumes that tree[] array is already set up
33
   return TRUE if we're ready to go
34
*/
35
 
36
Boolean setup(FilterRecordPtr pb){
37
        int i;
38
        extern int chunksize;
39
 
40
        INITRANDSEED();
41
        var['X'] = pb->imageSize.h;
42
        var['Y'] = pb->imageSize.v;
43
        var['Z'] = nplanes;
44
        var['D'] = 1024;
45
        var['M'] = ff_c2m(var['X'],var['Y'])/2;
46
 
47
        /* initialise flags for tracking special variable usage */
48
        for( i=0 ; i<0x100 ; i++ )
49
                varused[i] = 0;
50
        srcradused = 0;
51
        for(i=0;i<nplanes;++i){
52
//char s[100];sprintf(s,"expr[%d]=%#x",i,expr[i]);dbg(s);
53
                if( tree[i] || ( tree[i] = parseexpr(expr[i]) ) )
54
                        checkvars(tree[i],varused,&srcradused);
55
                else
56
                        break;
57
        }
58
        needinput = (srcradused || varused['r'] || varused['g'] || varused['b'] || varused['a']
59
                                                        || varused['i'] || varused['u'] || varused['v'] || varused['c']) ;
60
 
61
        return i==nplanes; /* all required expressions parse OK */
62
}
63
 
64
void evalpixel(unsigned char *outp,unsigned char *inp){
65
        int f,k;
66
 
67
        if(needinput){
68
                var['r'] = inp[0];
69
                var['g'] = nplanes > 1 ? inp[1] : 0;
70
                var['b'] = nplanes > 2 ? inp[2] : 0;
71
                var['a'] = nplanes > 3 ? inp[3] : 0;
72
 
73
                if(varused['i']) var['i'] = (( 76L*var['r'])+(150L*var['g'])+( 29L*var['b']))/256;
74
                if(varused['u']) var['u'] = ((-19L*var['r'])+(-37L*var['g'])+( 56L*var['b']))/256;
75
                if(varused['v']) var['v'] = (( 78L*var['r'])+(-65L*var['g'])+(-13L*var['b']))/256;
76
        }
77
        if(varused['d']) var['d'] = ff_c2d(var['X']/2-var['x'],var['Y']/2-var['y']);
78
        if(varused['m']) var['m'] = ff_c2m(var['X']/2-var['x'],var['Y']/2-var['y']);
79
 
80
        for( k=0 ; k<nplanes ; ++k ){
81
                if(needinput)
82
                        var['c'] = inp[k];
83
                var['z'] = k;
84
                f = eval(tree[k]);
85
                outp[k] = f<0 ? 0 : ( f>255 ? 255 : f ); // clamp channel value to 0-255
86
        }
87
}
88
 
89
OSErr process(FilterRecordPtr pb,Boolean progress,
90
                          Rect *inRect,Rect *filterRect,Rect *outRect,
91
                          void *outData,long outRowBytes){
92
        unsigned char *inrow,*outrow,*inp,*outp;
93
        int j,i,ncols = filterRect->right - filterRect->left;
94
        long t,ticks = TICKCOUNT();
95
 
96
        long inoffset = (long)pb->inRowBytes*(filterRect->top - inRect->top)
97
                                        + (long)nplanes*(filterRect->left - inRect->left),
98
                 outoffset = (long)outRowBytes*(filterRect->top - outRect->top)
99
                                         + (long)nplanes*(filterRect->left - outRect->left);
100
/*
101
{char s[0x100];sprintf(s,"process: inoffset=%d outoffset=%d inData=%#x inRect=(%d,%d,%d,%d) filterRect=(%d,%d,%d,%d)",
102
        inoffset,outoffset,pb->inData,
103
        inRect->left,inRect->top,inRect->right,inRect->bottom,
104
        filterRect->left,filterRect->top,filterRect->right,filterRect->bottom);dbg(s);}
105
*/
106
 
107
        for( inrow = (unsigned char*)pb->inData + inoffset, outrow = (unsigned char*)outData + outoffset,
108
                        j = filterRect->bottom - filterRect->top, var['y'] = filterRect->top
109
                        ; j-- ; ++var['y'], inrow += pb->inRowBytes, outrow += outRowBytes ){
110
 
111
                for ( inp=inrow, outp=outrow, i=ncols, var['x']=filterRect->left ; i-- ; ++var['x'], inp+=nplanes, outp+=nplanes ){
112
                        evalpixel(outp,inp); /* var['x'] & var['y'] are implicit parameters */
113
                }
114
 
115
                if(progress && (t = TICKCOUNT()) > ticks){
116
                        ticks = t + TICKS_SEC/4;
117
                        if(pb->abortProc())
118
                                return userCanceledErr;
119
                        else
120
                                pb->progressProc(var['y'] - pb->filterRect.top,pb->filterRect.bottom - pb->filterRect.top);
121
                }
122
#ifdef MAC_ENV
123
                else{
124
                        /* to reduce annoying delays during typing of expressions,
125
                           immediately abort preview calculation if a key or mouse has been pressed. */
126
                        EventRecord event;
127
                        if(EventAvail(mDownMask|keyDownMask|autoKeyMask,&event))
128
                                return userCanceledErr;
129
                }
130
#endif
131
        }
132
        return noErr;
133
 
134
}
135
 
136
OSErr process_scaled(FilterRecordPtr pb,Boolean progress,
137
                          Rect *inRect,Rect *filterRect,Rect *outRect,
138
                          void *outData,long outRowBytes,double zoom){
139
        unsigned char *inrow,*outrow,*outp;
140
        int j,i,ncols = filterRect->right - filterRect->left;
141
        long t,ticks = TICKCOUNT();
142
        double x,y;
143
/*
144
{char s[0x100];sprintf(s,"process_scaled: pb->inData=%#x  outData=%#x\n\
145
inRect=(%d,%d,%d,%d) filterRect=(%d,%d,%d,%d) outRect=(%d,%d,%d,%d)\n\
146
pb->filterRect=(%d,%d,%d,%d)\n",
147
        pb->inData,outData,
148
        inRect->left,inRect->top,inRect->right,inRect->bottom,
149
        filterRect->left,filterRect->top,filterRect->right,filterRect->bottom,
150
        outRect->left,outRect->top,outRect->right,outRect->bottom,
151
        pb->filterRect.left,pb->filterRect.top,pb->filterRect.right,pb->filterRect.bottom); dbg(s);}
152
*/
153
        if(needinput && !pb->inData){
154
                simplealert("Input error (process_scaled: pb->inData == NULL). This problem is being investigated. Cannot apply the filter; please re-launch Photoshop and try again.");
155
                return userCanceledErr;
156
        }else
157
                for( j = outRect->top, outrow = (unsigned char*)outData, y = filterRect->top
158
                                ; j < outRect->bottom ; ++j, outrow += outRowBytes, y += zoom ){
159
                        var['y'] = y;
160
                        inrow = (unsigned char*)pb->inData
161
                                + (var['y'] - inRect->top)*pb->inRowBytes
162
                                - (long)nplanes*inRect->left;
163
 
164
                        for( outp=outrow, i=outRect->left, x=filterRect->left ; i<outRect->right ; ++i, outp+=nplanes, x+=zoom ){
165
                                var['x'] = x;
166
                                evalpixel(outp,inrow + (long)var['x']*nplanes); /* var['x'] & var['y'] are implicit parameters */
167
                        }
168
 
169
                        if(progress && (t = TICKCOUNT()) > ticks){
170
                                ticks = t + TICKS_SEC/4;
171
                                if(pb->abortProc())
172
                                        return userCanceledErr;
173
                                else
174
                                        pb->progressProc((int)y - pb->filterRect.top,pb->filterRect.bottom - pb->filterRect.top);
175
                        }
176
#ifdef MAC_ENV
177
                        else{
178
                                /* to stop delays during typing of expressions,
179
                                   immediately abort preview calculation if a key or mouse has been pressed. */
180
                                EventRecord event;
181
                                if(EventAvail(mDownMask|keyDownMask|autoKeyMask,&event))
182
                                        return userCanceledErr;
183
                        }
184
#endif
185
                }
186
 
187
        return noErr;
188
}