Subversion Repositories filter_foundry

Rev

Rev 23 | Rev 66 | 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-6 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 "ff.h"
  21. #include "symtab.h"
  22. #include "node.h"
  23. #include "funcs.h"
  24. #include "y.tab.h"
  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();
  40.         var['X'] = pb->filterRect.right - pb->filterRect.left;
  41.         var['Y'] = pb->filterRect.bottom - pb->filterRect.top;
  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.  
  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.  */
  103.  
  104. OSErr process_scaled(FilterRecordPtr pb, Boolean progress,
  105.                           Rect *filterRect, Rect *outRect,
  106.                           void *outData, long outRowBytes, double zoom){
  107.         unsigned char *inrow,*outrow,*outp;
  108.         int j,i;
  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,
  116.         pb->inRect->left,pb->inRect->top,pb->inRect->right,pb->inRect->bottom,
  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){
  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.");
  125.                 return userCanceledErr;
  126.         }else
  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)
  131.                         inrow = (unsigned char*)pb->inData
  132.                                         + ((long)y + pb->filterRect.top - pb->inRect.top)*pb->inRowBytes
  133.                                         + (long)nplanes*(pb->filterRect.left - pb->inRect.left);
  134.        
  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)
  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. }
  162.