Rev 8 | Rev 29 | 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 | /* This is PLATFORM INDEPENDENT user interface code - mainly dialog logic */ |
||
21 | |||
22 | #include "ff.h" |
||
23 | |||
24 | #include "piproperties.h" |
||
25 | |||
26 | #include "node.h" |
||
27 | #include "funcs.h" |
||
28 | #include "y.tab.h" |
||
29 | #include "choosefile.h" |
||
30 | |||
31 | PSPixelMap preview_pmap; |
||
32 | PSPixelMask preview_pmask; |
||
33 | Handle preview_handle; |
||
34 | UIRECT preview_rect; |
||
35 | int preview_w,preview_h; |
||
36 | Point preview_scroll; |
||
37 | Boolean preview_complete = false; |
||
38 | |||
39 | Boolean setup_preview(FilterRecordPtr pb){ |
||
40 | |||
41 | //dbg("setup_preview"); |
||
42 | |||
43 | if(pb->displayPixels && pb->advanceState){ |
||
44 | |||
45 | preview_w = MIN(preview_rect.right - preview_rect.left - 2,pb->filterRect.right - pb->filterRect.left); |
||
46 | preview_h = MIN(preview_rect.bottom - preview_rect.top - 2,pb->filterRect.bottom - pb->filterRect.top); |
||
47 | |||
48 | preview_pmap.version = 1; |
||
49 | preview_pmap.bounds.left = preview_pmap.bounds.top = 0; |
||
50 | preview_pmap.bounds.right = preview_w; |
||
51 | preview_pmap.bounds.bottom = preview_h; |
||
52 | preview_pmap.imageMode = nplanes>1 ? plugInModeRGBColor : plugInModeGrayScale; |
||
53 | preview_pmap.rowBytes = nplanes*preview_w; |
||
54 | preview_pmap.colBytes = nplanes; |
||
55 | preview_pmap.planeBytes = 1; /*interleaved*/ |
||
56 | // preview_pmap.baseAddr = preview_data; |
||
57 | /* baseAddr must be set before using pixelmap */ |
||
58 | |||
59 | //--------------------------------------------------------------------------- |
||
60 | // Fields new in version 1: |
||
61 | //--------------------------------------------------------------------------- |
||
62 | preview_pmap.mat = NULL; |
||
63 | |||
64 | if(nplanes==4){ |
||
65 | preview_pmask.next = NULL; |
||
66 | // preview_pmask.maskData = preview_data+3; |
||
67 | preview_pmask.rowBytes = preview_pmap.rowBytes; |
||
68 | preview_pmask.colBytes = nplanes; |
||
69 | preview_pmask.maskDescription = kSimplePSMask; |
||
70 | preview_pmap.masks = &preview_pmask; |
||
71 | }else |
||
72 | preview_pmap.masks = NULL; |
||
73 | |||
74 | preview_handle = PINEWHANDLE((long)preview_h * preview_pmap.rowBytes); |
||
75 | }else |
||
76 | preview_handle = NULL; |
||
77 | return preview_handle != NULL; |
||
78 | |||
79 | //--------------------------------------------------------------------------- |
||
80 | // Fields new in version 2: |
||
81 | //--------------------------------------------------------------------------- |
||
82 | // preview_pmap.pixelOverlays; |
||
83 | // preview_pmap.colorManagementOptions; |
||
84 | |||
85 | // setup(pb); // prepare for evaluations |
||
86 | } |
||
87 | |||
88 | void dispose_preview(){ |
||
89 | if(preview_handle){ |
||
90 | PIDISPOSEHANDLE(preview_handle); |
||
91 | preview_handle = NULL; |
||
92 | } |
||
93 | } |
||
94 | |||
95 | void recalc_preview(FilterRecordPtr pb,DIALOGREF dp){ |
||
96 | extern int srcradused,needinput; |
||
97 | extern double zoomfactor; |
||
98 | OSErr e; |
||
99 | int j,n,scaledw,scaledh,imgw,imgh; |
||
100 | Rect r,outRect; |
||
101 | Ptr outrow; |
||
102 | |||
103 | if(preview_handle){ |
||
104 | |||
105 | /* size of previewed area, of source image; but no larger than filtered area (selection) */ |
||
106 | scaledw = zoomfactor*preview_w; |
||
107 | if(scaledw > (pb->filterRect.right - pb->filterRect.left)) |
||
108 | scaledw = (pb->filterRect.right - pb->filterRect.left); |
||
109 | scaledh = zoomfactor*preview_h; |
||
110 | if(scaledh > (pb->filterRect.bottom - pb->filterRect.top)) |
||
111 | scaledh = (pb->filterRect.bottom - pb->filterRect.top); |
||
112 | |||
113 | /* scale clipped preview area down again - this becomes the pixel size of preview */ |
||
114 | imgw = scaledw/zoomfactor; |
||
115 | if(imgw > preview_w) |
||
116 | imgw = preview_w; |
||
117 | imgh = scaledh/zoomfactor; |
||
118 | if(imgh > preview_h) |
||
119 | imgh = preview_h; |
||
120 | |||
121 | // Use to set the phase of the checkerboard: |
||
122 | preview_pmap.maskPhaseRow = preview_scroll.v/zoomfactor; |
||
123 | preview_pmap.maskPhaseCol = preview_scroll.h/zoomfactor; |
||
124 | |||
125 | /* compute source data rectangle (inRect) */ |
||
126 | |||
127 | /* centre preview on filtered part of input image, adding scroll offset */ |
||
128 | r.left = (pb->filterRect.left+pb->filterRect.right-scaledw)/2 + preview_scroll.h; |
||
129 | /* make sure it does not go outside the input area */ |
||
130 | if(r.left < pb->filterRect.left) |
||
131 | r.left = pb->filterRect.left; |
||
132 | else if(r.left > pb->filterRect.right-scaledw) |
||
133 | r.left = pb->filterRect.right-scaledw; |
||
134 | r.right = r.left + scaledw; |
||
135 | |||
136 | /* now compute for vertical */ |
||
137 | r.top = (pb->filterRect.top+pb->filterRect.bottom-scaledh)/2 + preview_scroll.v; |
||
138 | if(r.top < pb->filterRect.top) |
||
139 | r.top = pb->filterRect.top; |
||
140 | else if(r.top > pb->filterRect.bottom-scaledh) |
||
141 | r.top = pb->filterRect.bottom-scaledh; |
||
142 | r.bottom = r.top + scaledh; |
||
143 | |||
144 | /* if formulae need random access to image - src(), rad() - we must request entire area: */ |
||
145 | if(srcradused){ |
||
146 | SETRECT(pb->inRect,0,0,pb->imageSize.h,pb->imageSize.v); |
||
147 | }else |
||
148 | pb->inRect = r; |
||
149 | |||
150 | pb->outRect = pb->inRect; |
||
151 | SETRECT(pb->maskRect,0,0,0,0); |
||
152 | pb->inLoPlane = pb->outLoPlane = 0; |
||
153 | pb->inHiPlane = pb->outHiPlane = nplanes-1; |
||
154 | |||
155 | //dbg("recalc_preview: about to call advanceState()"); |
||
156 | if( !needinput || !(e = pb->advanceState()) ){ |
||
157 | Ptr outptr = PILOCKHANDLE(preview_handle,false); |
||
158 | int blankrows = (preview_h-imgh)/2, |
||
159 | blankcols = (preview_w-imgw)/2; |
||
160 | |||
161 | INITRANDSEED(); |
||
162 | //dbg("recalc_preview: about to call process()"); |
||
163 | |||
164 | SETRECT(outRect,0,0,imgw,imgh); |
||
165 | |||
166 | e = process_scaled(pb,false, |
||
167 | &pb->inRect,&r,&outRect, |
||
168 | outptr+preview_pmap.rowBytes*blankrows+nplanes*blankcols,preview_pmap.rowBytes, |
||
169 | zoomfactor); |
||
170 | if(blankrows){ |
||
171 | memset(outptr,0xff,preview_pmap.rowBytes*blankrows); |
||
172 | n = preview_h - blankrows - imgh; /* blank rows below preview */ |
||
173 | memset(outptr+preview_pmap.rowBytes*(blankrows+imgh),0xff,preview_pmap.rowBytes*n); |
||
174 | } |
||
175 | if(blankcols){ |
||
176 | n = preview_w - blankcols - imgw; /* blank columns on right side of preview */ |
||
177 | outrow = outptr+preview_pmap.rowBytes*blankrows; |
||
178 | for( j = blankrows ; j < preview_h - blankrows ; ++j ){ |
||
179 | memset(outrow,0xff,nplanes*blankcols); |
||
180 | memset(outrow+nplanes*(blankcols+imgw),0xff,nplanes*n); |
||
181 | outrow += preview_pmap.rowBytes; |
||
182 | } |
||
183 | } |
||
184 | |||
185 | if(!e){ |
||
186 | preview_complete = true; |
||
187 | |||
188 | #ifdef WIN_ENV |
||
189 | { |
||
190 | extern HWND preview_hwnd; |
||
191 | HDC hdc = GetDC(preview_hwnd); |
||
192 | |||
193 | //dbg("recalc_preview: about to call drawpreview()"); |
||
194 | drawpreview(dp,hdc,outptr); |
||
195 | |||
196 | ReleaseDC(preview_hwnd,hdc); |
||
197 | } |
||
198 | #else |
||
199 | { |
||
200 | GrafPtr saveport; |
||
201 | |||
202 | GetPort(&saveport); |
||
203 | SetPortDialogPort(dp); |
||
204 | |||
205 | drawpreview(dp,NULL,outptr); |
||
206 | |||
207 | SetPort(saveport); |
||
208 | } |
||
209 | #endif |
||
210 | } |
||
211 | |||
212 | PIUNLOCKHANDLE(preview_handle); |
||
213 | |||
214 | }else{ char s[0x100]; |
||
215 | sprintf(s,"recalc_preview: advanceState failed (%d)\n\ |
||
216 | inRect=(%d,%d,%d,%d) filterRect=(%d,%d,%d,%d) inLoPlane=%d inHiPlane=%d ", |
||
217 | e, |
||
218 | pb->inRect.left,pb->inRect.top,pb->inRect.right,pb->inRect.bottom, |
||
219 | pb->filterRect.left,pb->filterRect.top,pb->filterRect.right,pb->filterRect.bottom, |
||
220 | pb->inLoPlane,pb->inHiPlane); |
||
221 | dbg(s); |
||
222 | } |
||
223 | } |
||
224 | } |
||
225 | |||
226 | OSErr drawpreview(DIALOGREF dp,void *hdc,Ptr imageptr){ |
||
227 | int32 watchsusp; |
||
228 | OSErr e = noErr; |
||
229 | VRect srcRect; |
||
230 | UIRECT imagebounds; |
||
231 | |||
232 | if(preview_handle && preview_complete){ |
||
233 | |||
234 | srcRect = preview_pmap.bounds; |
||
235 | |||
236 | imagebounds.left = (preview_rect.left+preview_rect.right-preview_w)/2; |
||
237 | imagebounds.top = (preview_rect.top+preview_rect.bottom-preview_h)/2; |
||
238 | imagebounds.right = imagebounds.left + preview_w; |
||
239 | imagebounds.bottom = imagebounds.top + preview_h; |
||
240 | |||
241 | preview_pmap.baseAddr = imageptr;//PILOCKHANDLE(preview_handle,false); |
||
242 | preview_pmask.maskData = imageptr+3; |
||
243 | |||
244 | if(gpb->propertyProcs->getPropertyProc){ |
||
245 | gpb->propertyProcs->getPropertyProc(kPhotoshopSignature,propWatchSuspension,0,&watchsusp,NULL); |
||
246 | gpb->propertyProcs->setPropertyProc(kPhotoshopSignature,propWatchSuspension,0,watchsusp+1,NULL); |
||
247 | } |
||
248 | e = gpb->displayPixels(&preview_pmap,&srcRect,imagebounds.top,imagebounds.left,hdc); |
||
249 | |||
250 | if(gpb->propertyProcs->getPropertyProc) |
||
251 | gpb->propertyProcs->setPropertyProc(kPhotoshopSignature,propWatchSuspension,0,watchsusp,NULL); |
||
252 | } |
||
253 | return e; |
||
254 | } |
||
255 | |||
256 | #if 0 |
||
257 | // old process-then-scale preview code |
||
258 | if(scaleddata = PINEWHANDLE((long)nplanes*scaledw*scaledh)){ |
||
259 | Ptr scaledptr = PILOCKHANDLE(scaleddata,false); |
||
260 | //process(pb,false,&pb->inRect,&r,&r,outptr,preview_pmap.rowBytes) |
||
261 | long scaledrb = (long)nplanes*scaledw; |
||
262 | |||
263 | if(!(e = process(pb,false,&pb->inRect,&r,&r,scaledptr,scaledrb)){ |
||
264 | |||
265 | /* copy data from scaledptr to outptr, scaling as we go */ |
||
266 | if(zoomfactor == 1.) |
||
267 | memcpy(outptr,scaledptr,(long)nplanes*preview_w*preview_h); |
||
268 | else{ |
||
269 | int blankrows = (preview_h-imgh)/2, |
||
270 | blankcols = (preview_w-imgw)/2; |
||
271 | |||
272 | memset(outptr,0xff,preview_pmap.rowBytes*blankrows); |
||
273 | memset(outptr+preview_pmap.rowBytes*(preview_h-blankrows),0xff,preview_pmap.rowBytes*blankrows); |
||
274 | |||
275 | outrow = outptr+preview_pmap.rowBytes*blankrows; |
||
276 | for( j=blankrows,y=0. ; j<preview_h-blankrows ; ++j,y+=zoomfactor ){ |
||
277 | memset(outrow,0xff,nplanes*blankcols); |
||
278 | memset(outrow+nplanes*(preview_w-blankcols),0xff,nplanes*blankcols); |
||
279 | outrow += nplanes*blankcols; |
||
280 | inrow = scaledptr + scaledrb*(int)y; |
||
281 | for( i=blankcols,x = 0. ; i<(preview_w-blankcols) ; ++i,x+=zoomfactor){ |
||
282 | inpix = inrow + nplanes*(int)x ; |
||
283 | for(k=0;k<nplanes;++k) |
||
284 | *outrow++ = inpix[k]; |
||
285 | } |
||
286 | outrow += nplanes*blankcols; |
||
287 | } |
||
288 | } |
||
289 | } |
||
290 | PIDISPOSEHANDLE(scaleddata); |
||
291 | }else e = memFullErr; |
||
292 | #endif |