Subversion Repositories filter_foundry

Rev

Rev 66 | Rev 85 | 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
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 <stdio.h>
21
//#include <sound.h>
22
 
23
#include "ff.h"
8 toby 24
 
2 toby 25
#include "node.h"
8 toby 26
#include "y.tab.h"
2 toby 27
#include "scripting.h"
28
 
29
struct node *tree[4];
30
char *err[4];
71 toby 31
int errpos[4],errstart[4],nplanes,cnvused,srcradused,chunksize,toprow;
2 toby 32
value_type slider[8],cell[0x100],map[4][0x100];
33
char *expr[4],*defaultexpr[]={"r","g","b","a"};
37 toby 34
long maxSpace;
71 toby 35
globals_t *gdata;
36
FilterRecordPtr gpb;
2 toby 37
 
38
#ifdef MAC_ENV
62 toby 39
        #define hDllInstance NULL /* fake this Windows-only global */
2 toby 40
#endif
41
 
42
extern struct sym_rec predefs[];
71 toby 43
extern int nplanes,varused[];
2 toby 44
 
45
 
15 toby 46
int checkandinitparams(Handle params);
2 toby 47
 
48
DLLEXPORT MACPASCAL
49
void ENTRYPOINT(short selector,FilterRecordPtr pb,long *data,short *result){
50
        OSErr e = noErr;
51
        static Boolean wantdialog = false;
52
 
53
        EnterCodeResource();
54
 
55
        gpb = pb;
56
 
57
        if(!*data){
58
                gdata = (globals_t*)( *data = (long)malloc(sizeof(globals_t)) ) ;
59
                gdata->standalone = gdata->parmloaded = false;
60
        }else
61
                gdata = (globals_t*)*data;
62
 
63
        nplanes = MIN(pb->planes,4);
64
 
65
        switch (selector){
66
        case filterSelectorAbout:
67
                DoAbout((AboutRecordPtr)pb);
68
                break;
69
        case filterSelectorParameters:
70
//              dbg("filterSelectorParameters");
15 toby 71
                wantdialog = true;
2 toby 72
                break;
73
        case filterSelectorPrepare:
74
//              dbg("filterSelectorPrepare");
75
                DoPrepare(pb);
76
                init_symtab(predefs); // ready for parser calls
77
                break;
78
        case filterSelectorStart:
79
//              dbg("filterSelectorStart");
80
 
15 toby 81
                if(!pb->parameters){
82
                        //dbg("pb->parameters = PINEWHANDLE(0)"),
83
                        pb->parameters = PINEWHANDLE(0); /* initialise the parameter handle that Photoshop keeps for us */
84
                        if(!pb->parameters) dbg("filterSelectorStart NULL handle @ PINEWHANDLE(0)");
85
                }
2 toby 86
 
15 toby 87
                wantdialog |= checkandinitparams(pb->parameters);
88
 
89
                /* wantdialog = false means that we never got a Parameters call, so we're not supposed to ask user */
2 toby 90
                if( wantdialog && (!gdata->standalone || gdata->parm.popDialog) ){
91
                        if( maindialog(pb) ){
15 toby 92
                                //dbg("maindialog OK!");
93
                                /* update stored parameters from new user settings */
2 toby 94
                                saveparams(pb->parameters);
95
                        }else
96
                                e = userCanceledErr;
97
                }
18 toby 98
                wantdialog = false;
2 toby 99
 
100
                if(!e){
101
                        if(setup(pb)){
102
                                DoStart(pb);
103
                        }else{
104
                                SYSBEEP(1);
105
                                e = filterBadParameters;
106
                        }
107
                }
108
                break;
109
        case filterSelectorContinue:
110
                e = DoContinue(pb);
111
                break;
112
        case filterSelectorFinish:
113
                DoFinish(pb);
114
                break;
115
        default:
116
                e = filterBadParameters;
117
        }
118
 
119
        *result = e;
120
 
121
        ExitCodeResource();
122
}
123
 
15 toby 124
int checkandinitparams(Handle params){
125
        char *reasonstr,*reason;
21 toby 126
        int i,f,showdialog;
2 toby 127
 
23 toby 128
        if( (f = !(params && readparams(params,false,&reasonstr))) ){
2 toby 129
                /* either the parameter handle was uninitialised,
130
                   or the parameter data couldn't be read; set default values */
131
 
132
                if(readPARMresource(hDllInstance,&reason))
133
                        gdata->standalone = true;
134
                else{
21 toby 135
                        // no saved settings (not standalone)
2 toby 136
                        for(i=0;i<8;++i)
137
                                slider[i] = i*10+100;
138
                        for(i=4;i--;)
139
                                expr[i] = my_strdup(defaultexpr[i]);
140
                }
141
        }
21 toby 142
 
143
        // let scripting system change parameters, if we're scripted
144
        // user may want to force display of dialog during scripting playback 
145
        showdialog = ReadScriptParamsOnRead();
2 toby 146
 
15 toby 147
        /* sanity check for NULL expression pointers (?) */
2 toby 148
        for(i=4;i--;)
149
                if(!expr[i]) expr[i] = my_strdup(defaultexpr[i]);
15 toby 150
 
151
        saveparams(params); /* keep what we got */
21 toby 152
        return f || showdialog;
2 toby 153
}
154
 
155
void DoPrepare(FilterRecordPtr pb){
156
        int i;
157
 
158
        for(i=4;i--;){
8 toby 159
                if(expr[i]||tree[i]) DBG("expr[] or tree[] non-NULL in Prepare!");
2 toby 160
                expr[i] = NULL;
161
                tree[i] = NULL;
162
        }
37 toby 163
        maxSpace = pb->maxSpace;
2 toby 164
}
165
 
166
void RequestNext(FilterRecordPtr pb,long toprow){
167
        /* Request next block of the image */
168
 
169
        pb->inLoPlane = pb->outLoPlane = 0;
170
        pb->inHiPlane = pb->outHiPlane = nplanes-1;
171
 
66 toby 172
        // if any of the formulae involve random access to image pixels,
173
        // must ask for the entire image
2 toby 174
        if(srcradused){
175
                SETRECT(pb->inRect,0,0,pb->imageSize.h,pb->imageSize.v);
176
        }else{
66 toby 177
                // otherwise, process the filtered area, by chunksize parts
2 toby 178
                pb->inRect.left = pb->filterRect.left;
179
                pb->inRect.right = pb->filterRect.right;
180
                pb->inRect.top = toprow;
181
                pb->inRect.bottom = MIN(toprow + chunksize,pb->filterRect.bottom);
71 toby 182
 
183
                if(cnvused){
184
                        // cnv() needs one extra pixel in each direction
185
                        if(pb->inRect.left > 0)
186
                                --pb->inRect.left;
187
                        if(pb->inRect.right < pb->imageSize.h)
188
                                ++pb->inRect.right;
189
                        if(pb->inRect.top > 0)
190
                                --pb->inRect.top;
191
                        if(pb->inRect.bottom < pb->imageSize.v)
192
                                ++pb->inRect.bottom;
193
                }
2 toby 194
        }
66 toby 195
        pb->outRect = pb->filterRect;
2 toby 196
/*
197
{char s[0x100];sprintf(s,"RequestNext srcradused=%d inRect=(%d,%d,%d,%d) filterRect=(%d,%d,%d,%d)",
198
        srcradused,
199
        pb->inRect.left,pb->inRect.top,pb->inRect.right,pb->inRect.bottom,
200
        pb->filterRect.left,pb->filterRect.top,pb->filterRect.right,pb->filterRect.bottom);dbg(s);}
201
*/
202
}
203
 
204
void DoStart(FilterRecordPtr pb){
205
//dbg("DoStart");
206
        /* if src() or rad() functions are used, random access to the image data is required,
207
           so we must request the entire image in a single chunk. */
208
        chunksize = srcradused ? (pb->filterRect.bottom - pb->filterRect.top) : CHUNK_ROWS;
209
        toprow = pb->filterRect.top;
210
        RequestNext(pb,toprow);
211
}
212
 
213
OSErr DoContinue(FilterRecordPtr pb){
214
        OSErr e = noErr;
71 toby 215
        Rect fr;
216
        long outoffset;
2 toby 217
 
71 toby 218
        if(srcradused)
219
                fr = pb->filterRect;  // filter whole selection at once
220
        else if(cnvused){
221
                // we've requested one pixel extra all around
222
                // (see RequestNext()), just for access purposes. But filter
223
                // original selection only.
224
                fr.left = pb->filterRect.left;
225
                fr.right = pb->filterRect.right;
226
                fr.top = toprow;
227
                fr.bottom = MIN(toprow + chunksize,pb->filterRect.bottom);
228
        }else  // filter whatever portion we've been given
229
                fr = pb->inRect;
230
 
231
        outoffset = (long)pb->outRowBytes*(fr.top - pb->outRect.top)
232
                                + (long)nplanes*(fr.left - pb->outRect.left);
233
 
234
        if(!(e = process_scaled(pb, true, &fr, &fr,
62 toby 235
                                (Ptr)pb->outData+outoffset, pb->outRowBytes, 1.)))
236
        {
2 toby 237
                toprow += chunksize;
238
                if(toprow < pb->filterRect.bottom)
239
                        RequestNext(pb,toprow);
240
                else{
241
                        SETRECT(pb->inRect,0,0,0,0);
242
                        pb->outRect = pb->maskRect = pb->inRect;
243
                }
244
        }
245
        return e;
246
}
247
 
248
void DoFinish(FilterRecordPtr pb){
249
        int i;
250
 
251
        WriteScriptParamsOnRead();
252
 
253
        for(i=4;i--;){
254
                freetree(tree[i]);
255
                if(expr[i]) free(expr[i]);
256
        }
257
}