Subversion Repositories filter_foundry

Rev

Rev 106 | Rev 128 | 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
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
#include "ff.h"
94 toby 21
 
2 toby 22
#include "symtab.h"
23
#include "node.h"
24
#include "funcs.h"
8 toby 25
#include "y.tab.h"
2 toby 26
 
27
extern value_type var[];
94 toby 28
extern int nplanes,varused[],cnvused;
2 toby 29
extern struct node *tree[];
66 toby 30
 
31
// points to first row, first column of selection image data
32
// this is used by src() and cnv() functions to access pixels
33
unsigned char *image_ptr;
34
 
2 toby 35
int needinput;
36
 
37
/* get prepared to evaluate expression trees--
38
   this assumes that tree[] array is already set up
39
   return TRUE if we're ready to go
40
*/
41
 
94 toby 42
// minimum setup required when formulae have not changed,
43
// and a new preview is to be generated. (Called by recalc_preview())
44
void evalinit(){
45
        INITRANDSEED();
46
}
47
 
48
// full setup for evaluation, called when formulae have changed.
2 toby 49
Boolean setup(FilterRecordPtr pb){
50
        int i;
51
 
117 dmarschall 52
        // Attention: If you introduce new variables, please define them also in lexer.l
53 toby 53
        var['X'] = pb->filterRect.right - pb->filterRect.left;
54
        var['Y'] = pb->filterRect.bottom - pb->filterRect.top;
2 toby 55
        var['Z'] = nplanes;
56
        var['D'] = 1024;
57
        var['M'] = ff_c2m(var['X'],var['Y'])/2;
58
 
59
        /* initialise flags for tracking special variable usage */
71 toby 60
        for(i = 0; i < 0x100; i++)
2 toby 61
                varused[i] = 0;
94 toby 62
        needall = cnvused = 0;
71 toby 63
        for(i = 0; i < nplanes; ++i){
2 toby 64
//char s[100];sprintf(s,"expr[%d]=%#x",i,expr[i]);dbg(s);
71 toby 65
                if( tree[i] || (tree[i] = parseexpr(expr[i])) )
94 toby 66
                        checkvars(tree[i],varused,&cnvused,&needall);
2 toby 67
                else
68
                        break;
69
        }
94 toby 70
        needinput = ( cnvused || needall
71 toby 71
                || varused['r'] || varused['g'] || varused['b'] || varused['a']
72
                || varused['i'] || varused['u'] || varused['v'] || varused['c'] );
106 dmarschall 73
 
94 toby 74
        evalinit();
2 toby 75
        return i==nplanes; /* all required expressions parse OK */
76
}
77
 
78
void evalpixel(unsigned char *outp,unsigned char *inp){
79
        int f,k;
80
 
81
        if(needinput){
82
                var['r'] = inp[0];
83
                var['g'] = nplanes > 1 ? inp[1] : 0;
84
                var['b'] = nplanes > 2 ? inp[2] : 0;
85
                var['a'] = nplanes > 3 ? inp[3] : 0;
106 dmarschall 86
 
2 toby 87
                if(varused['i']) var['i'] = (( 76L*var['r'])+(150L*var['g'])+( 29L*var['b']))/256;
88
                if(varused['u']) var['u'] = ((-19L*var['r'])+(-37L*var['g'])+( 56L*var['b']))/256;
89
                if(varused['v']) var['v'] = (( 78L*var['r'])+(-65L*var['g'])+(-13L*var['b']))/256;
90
        }
66 toby 91
        if(varused['d']) var['d'] = ff_c2d(var['X']/2 - var['x'], var['Y']/2 - var['y']);
92
        if(varused['m']) var['m'] = ff_c2m(var['X']/2 - var['x'], var['Y']/2 - var['y']);
106 dmarschall 93
 
66 toby 94
        for(k = 0; k < nplanes; ++k){
2 toby 95
                if(needinput)
96
                        var['c'] = inp[k];
97
                var['z'] = k;
117 dmarschall 98
                var['p'] = k; // undocumented alias of z
2 toby 99
                f = eval(tree[k]);
66 toby 100
                outp[k] = f<0 ? 0 : (f>255 ? 255 : f); // clamp channel value to 0-255
2 toby 101
        }
102
}
103
 
53 toby 104
/* Zoom and filter image.
66 toby 105
 * Parameters:  pb          - Photoshop Filter parameter block
106
 *              progress    - whether to use Photoshop's progress bar
53 toby 107
 *                            (not appropriate during preview)
66 toby 108
 *              filterRect  - rectangle (within pb->inRect)
53 toby 109
 *                            of area to be filtered. This may not correspond
110
 *                            to pb->filterRect, it may be just a piece.
66 toby 111
 *              outPiece    - rectangle defining scaled output buffer.
112
 *                            In case of zoomed preview, this is physically
113
 *                            scaled FROM filterRect (or equal to filterRect
114
 *                            for unscaled 1:1 filtering).
53 toby 115
 *              outData     - pointer to output data buffer
116
 *              outRowBytes - row stride of output data buffer
106 dmarschall 117
 *              zoom        - pixel scale factor (both horiz & vert)
53 toby 118
 *                            e.g. 2.0 means 1 output pixel per 2 input pixels.
119
 */
2 toby 120
 
53 toby 121
OSErr process_scaled(FilterRecordPtr pb, Boolean progress,
66 toby 122
                          Rect *filterPiece, Rect *outPiece,
53 toby 123
                          void *outData, long outRowBytes, double zoom){
2 toby 124
        unsigned char *inrow,*outrow,*outp;
23 toby 125
        int j,i;
2 toby 126
        long t,ticks = TICKCOUNT();
127
        double x,y;
66 toby 128
 
106 dmarschall 129
        // find base pointer to selection image data
130
        image_ptr = (unsigned char*)pb->inData
131
                                + (long)pb->inRowBytes*(pb->filterRect.top - pb->inRect.top)
132
                                + (long)nplanes*(pb->filterRect.left - pb->inRect.left);
66 toby 133
 
106 dmarschall 134
        // j indexes scaled output rows
135
        for( j = outPiece->top, outrow = (unsigned char*)outData, y = filterPiece->top - pb->filterRect.top ;
136
                 j < outPiece->bottom ; ++j, outrow += outRowBytes, y += zoom )
137
        {
138
                var['y'] = y;  // index of corresponding *input* row, top of selection == 0
139
                inrow = image_ptr + (long)y*pb->inRowBytes;
66 toby 140
 
106 dmarschall 141
                // i indexes scaled output columns
142
                for( outp = outrow, i = outPiece->left, x = filterPiece->left - pb->filterRect.left ;
143
                         i < outPiece->right ; ++i, outp += nplanes, x += zoom )
53 toby 144
                {
106 dmarschall 145
                        var['x'] = x;  // index of corresponding *input* column, left of selection == 0
146
                        evalpixel(outp,inrow + (long)x*nplanes); /* var['x'] & var['y'] are implicit parameters */
147
                }
66 toby 148
 
106 dmarschall 149
                if(progress){
150
                        if((t = TICKCOUNT()) > ticks){
151
                                ticks = t + TICKS_SEC/4;
152
                                if(pb->abortProc())
153
                                        return userCanceledErr;
154
                                else
155
                                        pb->progressProc((int)y - pb->filterRect.top,pb->filterRect.bottom - pb->filterRect.top);
2 toby 156
                        }
106 dmarschall 157
                }
2 toby 158
#ifdef MAC_ENV
106 dmarschall 159
                else{
160
                        /* to stop delays during typing of expressions,
161
                           immediately abort preview calculation if a key or mouse has been pressed. */
162
                        EventRecord event;
163
                        if(EventAvail(mDownMask|keyDownMask|autoKeyMask,&event))
164
                                return userCanceledErr;
165
                }
2 toby 166
#endif
106 dmarschall 167
        }
2 toby 168
 
169
        return noErr;
170
}