Subversion Repositories filter_foundry

Rev

Rev 76 | Rev 106 | 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.  
  22. #include "symtab.h"
  23. #include "node.h"
  24. #include "funcs.h"
  25. #include "y.tab.h"
  26.  
  27. extern value_type var[];
  28. extern int nplanes,varused[],cnvused;
  29. extern struct node *tree[];
  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.  
  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.  
  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.
  49. Boolean setup(FilterRecordPtr pb){
  50.         int i;
  51.  
  52.         var['X'] = pb->filterRect.right - pb->filterRect.left;
  53.         var['Y'] = pb->filterRect.bottom - pb->filterRect.top;
  54.         var['Z'] = nplanes;
  55.         var['D'] = 1024;
  56.         var['M'] = ff_c2m(var['X'],var['Y'])/2;
  57.  
  58.         /* initialise flags for tracking special variable usage */
  59.         for(i = 0; i < 0x100; i++)
  60.                 varused[i] = 0;
  61.         needall = cnvused = 0;
  62.         for(i = 0; i < nplanes; ++i){
  63. //char s[100];sprintf(s,"expr[%d]=%#x",i,expr[i]);dbg(s);
  64.                 if( tree[i] || (tree[i] = parseexpr(expr[i])) )
  65.                         checkvars(tree[i],varused,&cnvused,&needall);
  66.                 else
  67.                         break;
  68.         }
  69.         needinput = ( cnvused || needall
  70.                 || varused['r'] || varused['g'] || varused['b'] || varused['a']
  71.                 || varused['i'] || varused['u'] || varused['v'] || varused['c'] );
  72.        
  73.         evalinit();
  74.         return i==nplanes; /* all required expressions parse OK */
  75. }
  76.  
  77. void evalpixel(unsigned char *outp,unsigned char *inp){
  78.         int f,k;
  79.  
  80.         if(needinput){
  81.                 var['r'] = inp[0];
  82.                 var['g'] = nplanes > 1 ? inp[1] : 0;
  83.                 var['b'] = nplanes > 2 ? inp[2] : 0;
  84.                 var['a'] = nplanes > 3 ? inp[3] : 0;
  85.                
  86.                 if(varused['i']) var['i'] = (( 76L*var['r'])+(150L*var['g'])+( 29L*var['b']))/256;
  87.                 if(varused['u']) var['u'] = ((-19L*var['r'])+(-37L*var['g'])+( 56L*var['b']))/256;
  88.                 if(varused['v']) var['v'] = (( 78L*var['r'])+(-65L*var['g'])+(-13L*var['b']))/256;
  89.         }
  90.         if(varused['d']) var['d'] = ff_c2d(var['X']/2 - var['x'], var['Y']/2 - var['y']);
  91.         if(varused['m']) var['m'] = ff_c2m(var['X']/2 - var['x'], var['Y']/2 - var['y']);
  92.        
  93.         for(k = 0; k < nplanes; ++k){
  94.                 if(needinput)
  95.                         var['c'] = inp[k];
  96.                 var['z'] = k;
  97.                 f = eval(tree[k]);
  98.                 outp[k] = f<0 ? 0 : (f>255 ? 255 : f); // clamp channel value to 0-255
  99.         }
  100. }
  101.  
  102. /* Zoom and filter image.
  103.  * Parameters:  pb          - Photoshop Filter parameter block
  104.  *              progress    - whether to use Photoshop's progress bar
  105.  *                            (not appropriate during preview)
  106.  *              filterRect  - rectangle (within pb->inRect)
  107.  *                            of area to be filtered. This may not correspond
  108.  *                            to pb->filterRect, it may be just a piece.
  109.  *              outPiece    - rectangle defining scaled output buffer.
  110.  *                            In case of zoomed preview, this is physically
  111.  *                            scaled FROM filterRect (or equal to filterRect
  112.  *                            for unscaled 1:1 filtering).
  113.  *              outData     - pointer to output data buffer
  114.  *              outRowBytes - row stride of output data buffer
  115.  *              zoom        - pixel scale factor (both horiz & vert)
  116.  *                            e.g. 2.0 means 1 output pixel per 2 input pixels.
  117.  */
  118.  
  119. OSErr process_scaled(FilterRecordPtr pb, Boolean progress,
  120.                           Rect *filterPiece, Rect *outPiece,
  121.                           void *outData, long outRowBytes, double zoom){
  122.         unsigned char *inrow,*outrow,*outp;
  123.         int j,i;
  124.         long t,ticks = TICKCOUNT();
  125.         double x,y;
  126.  
  127. /* char s[0x100];sprintf(s,"process_scaled: pb->inData=%p outData=%p\n\
  128. pb->inRect=(%d,%d,%d,%d) filterPiece=(%d,%d,%d,%d) outPiece=(%d,%d,%d,%d)\n\
  129. pb->fRect=(%d,%d,%d,%d)\n\
  130. top row offset (from inData) = %d\n\
  131. left row offset = %d\n",
  132.         pb->inData,outData,
  133.         pb->inRect.left,pb->inRect.top,pb->inRect.right,pb->inRect.bottom,
  134.         filterPiece->left,filterPiece->top,filterPiece->right,filterPiece->bottom,
  135.         outPiece->left,outPiece->top,outPiece->right,outPiece->bottom,
  136.         pb->filterRect.left,pb->filterRect.top,pb->filterRect.right,pb->filterRect.bottom,
  137.         filterPiece->top - pb->filterRect.top + pb->filterRect.top - pb->inRect.top,
  138.         filterPiece->left - pb->filterRect.left + pb->filterRect.left - pb->inRect.left); dbg(s); */
  139.  
  140.         if(needinput && !pb->inData){
  141.                 simplealert("Error (process_scaled: pb->inData == NULL)."
  142.                                         " This problem is being investigated. Cannot apply the filter;"
  143.                                         " please re-launch Photoshop and try again.");
  144.                 return userCanceledErr;
  145.         }else
  146.                 // find base pointer to selection image data
  147.                 image_ptr = (unsigned char*)pb->inData
  148.                                         + (long)pb->inRowBytes*(pb->filterRect.top - pb->inRect.top)
  149.                                         + (long)nplanes*(pb->filterRect.left - pb->inRect.left);
  150.  
  151.                 // j indexes scaled output rows
  152.                 for( j = outPiece->top, outrow = (unsigned char*)outData, y = filterPiece->top - pb->filterRect.top ;
  153.                          j < outPiece->bottom ; ++j, outrow += outRowBytes, y += zoom )
  154.                 {
  155.                         var['y'] = y;  // index of corresponding *input* row, top of selection == 0
  156.                         inrow = image_ptr + (long)y*pb->inRowBytes;
  157.  
  158.                         // i indexes scaled output columns
  159.                         for( outp = outrow, i = outPiece->left, x = filterPiece->left - pb->filterRect.left ;
  160.                                  i < outPiece->right ; ++i, outp += nplanes, x += zoom )
  161.                         {
  162.                                 var['x'] = x;  // index of corresponding *input* column, left of selection == 0
  163.                                 evalpixel(outp,inrow + (long)x*nplanes); /* var['x'] & var['y'] are implicit parameters */
  164.                         }
  165.        
  166.                         if(progress){
  167.                                 if((t = TICKCOUNT()) > ticks){
  168.                                         ticks = t + TICKS_SEC/4;
  169.                                         if(pb->abortProc())
  170.                                                 return userCanceledErr;
  171.                                         else
  172.                                                 pb->progressProc((int)y - pb->filterRect.top,pb->filterRect.bottom - pb->filterRect.top);
  173.                                 }
  174.                         }
  175. #ifdef MAC_ENV
  176.                         else{
  177.                                 /* to stop delays during typing of expressions,
  178.                                    immediately abort preview calculation if a key or mouse has been pressed. */
  179.                                 EventRecord event;
  180.                                 if(EventAvail(mDownMask|keyDownMask|autoKeyMask,&event))
  181.                                         return userCanceledErr;
  182.                         }
  183. #endif
  184.                 }
  185.  
  186.         return noErr;
  187. }
  188.