Subversion Repositories filter_foundry

Rev

Rev 8 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

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