Subversion Repositories filter_foundry

Rev

Rev 23 | Rev 66 | 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
53 toby 3
    Copyright (C) 2003-6 Toby Thain, toby@telegraphics.com.au
2 toby 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
 
39
        INITRANDSEED();
53 toby 40
        var['X'] = pb->filterRect.right - pb->filterRect.left;
41
        var['Y'] = pb->filterRect.bottom - pb->filterRect.top;
2 toby 42
        var['Z'] = nplanes;
43
        var['D'] = 1024;
44
        var['M'] = ff_c2m(var['X'],var['Y'])/2;
45
 
46
        /* initialise flags for tracking special variable usage */
47
        for( i=0 ; i<0x100 ; i++ )
48
                varused[i] = 0;
49
        srcradused = 0;
50
        for(i=0;i<nplanes;++i){
51
//char s[100];sprintf(s,"expr[%d]=%#x",i,expr[i]);dbg(s);
52
                if( tree[i] || ( tree[i] = parseexpr(expr[i]) ) )
53
                        checkvars(tree[i],varused,&srcradused);
54
                else
55
                        break;
56
        }
57
        needinput = (srcradused || varused['r'] || varused['g'] || varused['b'] || varused['a']
58
                                                        || varused['i'] || varused['u'] || varused['v'] || varused['c']) ;
59
 
60
        return i==nplanes; /* all required expressions parse OK */
61
}
62
 
63
void evalpixel(unsigned char *outp,unsigned char *inp){
64
        int f,k;
65
 
66
        if(needinput){
67
                var['r'] = inp[0];
68
                var['g'] = nplanes > 1 ? inp[1] : 0;
69
                var['b'] = nplanes > 2 ? inp[2] : 0;
70
                var['a'] = nplanes > 3 ? inp[3] : 0;
71
 
72
                if(varused['i']) var['i'] = (( 76L*var['r'])+(150L*var['g'])+( 29L*var['b']))/256;
73
                if(varused['u']) var['u'] = ((-19L*var['r'])+(-37L*var['g'])+( 56L*var['b']))/256;
74
                if(varused['v']) var['v'] = (( 78L*var['r'])+(-65L*var['g'])+(-13L*var['b']))/256;
75
        }
76
        if(varused['d']) var['d'] = ff_c2d(var['X']/2-var['x'],var['Y']/2-var['y']);
77
        if(varused['m']) var['m'] = ff_c2m(var['X']/2-var['x'],var['Y']/2-var['y']);
78
 
79
        for( k=0 ; k<nplanes ; ++k ){
80
                if(needinput)
81
                        var['c'] = inp[k];
82
                var['z'] = k;
83
                f = eval(tree[k]);
84
                outp[k] = f<0 ? 0 : ( f>255 ? 255 : f ); // clamp channel value to 0-255
85
        }
86
}
87
 
53 toby 88
/* Zoom and filter image.
89
 * Parameters:  pb          - Photoshop parameter block
90
 *              progress    - whether to call Photoshop's progress bar
91
 *                            (not appropriate during preview)
92
 *              filterRect  - rectangle (contained within pb->inRect)
93
 *                            of area to be filtered. This may not correspond
94
 *                            to pb->filterRect, it may be just a piece.
95
 *              outRect     - rectangle defining scaled output buffer,
96
 *                            physically scaled FROM filterRect
97
 *                            (= filterRect for unscaled 1:1 filtering).
98
 *              outData     - pointer to output data buffer
99
 *              outRowBytes - row stride of output data buffer
100
 *              zoom        - pixel scale factor (horiz & vert)
101
 *                            e.g. 2.0 means 1 output pixel per 2 input pixels.
102
 */
2 toby 103
 
53 toby 104
OSErr process_scaled(FilterRecordPtr pb, Boolean progress,
105
                          Rect *filterRect, Rect *outRect,
106
                          void *outData, long outRowBytes, double zoom){
2 toby 107
        unsigned char *inrow,*outrow,*outp;
23 toby 108
        int j,i;
2 toby 109
        long t,ticks = TICKCOUNT();
110
        double x,y;
111
/*
112
{char s[0x100];sprintf(s,"process_scaled: pb->inData=%#x  outData=%#x\n\
113
inRect=(%d,%d,%d,%d) filterRect=(%d,%d,%d,%d) outRect=(%d,%d,%d,%d)\n\
114
pb->filterRect=(%d,%d,%d,%d)\n",
115
        pb->inData,outData,
53 toby 116
        pb->inRect->left,pb->inRect->top,pb->inRect->right,pb->inRect->bottom,
2 toby 117
        filterRect->left,filterRect->top,filterRect->right,filterRect->bottom,
118
        outRect->left,outRect->top,outRect->right,outRect->bottom,
119
        pb->filterRect.left,pb->filterRect.top,pb->filterRect.right,pb->filterRect.bottom); dbg(s);}
120
*/
121
        if(needinput && !pb->inData){
53 toby 122
                simplealert("Error (process_scaled: pb->inData == NULL)."
123
                                        " This problem is being investigated. Cannot apply the filter;"
124
                                        " please re-launch Photoshop and try again.");
2 toby 125
                return userCanceledErr;
126
        }else
53 toby 127
                for( j = outRect->top, outrow = (unsigned char*)outData, y = filterRect->top - pb->filterRect.top ;
128
                         j < outRect->bottom ; ++j, outrow += outRowBytes, y += zoom )
129
                {
130
                        var['y'] = y; // counts *input* columns across selection (pb->filterRect)
2 toby 131
                        inrow = (unsigned char*)pb->inData
53 toby 132
                                        + ((long)y + pb->filterRect.top - pb->inRect.top)*pb->inRowBytes
133
                                        + (long)nplanes*(pb->filterRect.left - pb->inRect.left);
2 toby 134
 
53 toby 135
                        for( outp = outrow, i = outRect->left, x = filterRect->left - pb->filterRect.left ;
136
                                 i < outRect->right ; ++i, outp += nplanes, x += zoom )
137
                        {
138
                                var['x'] = x; // counts *input* rows across selection (pb->filterRect)
2 toby 139
                                evalpixel(outp,inrow + (long)var['x']*nplanes); /* var['x'] & var['y'] are implicit parameters */
140
                        }
141
 
142
                        if(progress && (t = TICKCOUNT()) > ticks){
143
                                ticks = t + TICKS_SEC/4;
144
                                if(pb->abortProc())
145
                                        return userCanceledErr;
146
                                else
147
                                        pb->progressProc((int)y - pb->filterRect.top,pb->filterRect.bottom - pb->filterRect.top);
148
                        }
149
#ifdef MAC_ENV
150
                        else{
151
                                /* to stop delays during typing of expressions,
152
                                   immediately abort preview calculation if a key or mouse has been pressed. */
153
                                EventRecord event;
154
                                if(EventAvail(mDownMask|keyDownMask|autoKeyMask,&event))
155
                                        return userCanceledErr;
156
                        }
157
#endif
158
                }
159
 
160
        return noErr;
161
}