Subversion Repositories filter_foundry

Rev

Rev 2 | Rev 15 | 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 <stdio.h>
  21. //#include <sound.h>
  22.  
  23. #include "ff.h"
  24.  
  25. #include "node.h"
  26. #include "y.tab.h"
  27. #include "scripting.h"
  28.  
  29. struct node *tree[4];
  30. char *err[4];
  31. int errpos[4],errstart[4],nplanes,srcradused,chunksize,toprow;
  32. value_type slider[8],cell[0x100],map[4][0x100];
  33. char *expr[4],*defaultexpr[]={"r","g","b","a"};
  34.  
  35. #ifdef MAC_ENV
  36.         /* fake this global on Mac (in Windows build, it's defined in dllmain.c) */
  37.         Handle hDllInstance = NULL;
  38. #endif
  39.  
  40. extern struct sym_rec predefs[];
  41. extern int nplanes,varused[],srcradused;
  42.  
  43. globals_t *gdata;
  44. FilterRecordPtr gpb;
  45.  
  46. void checkandinitparams(long *data,Handle params);
  47.  
  48. DLLEXPORT MACPASCAL
  49. void ENTRYPOINT(short selector,FilterRecordPtr pb,long *data,short *result){
  50.         OSErr e = noErr;
  51.         static Boolean wantdialog = false;
  52.        
  53.         EnterCodeResource();
  54.        
  55.         gpb = pb;
  56.        
  57.         if(!*data){
  58.                 gdata = (globals_t*)( *data = (long)malloc(sizeof(globals_t)) ) ;
  59.                 gdata->standalone = gdata->parmloaded = false;
  60.         }else
  61.                 gdata = (globals_t*)*data;
  62.        
  63.         nplanes = MIN(pb->planes,4);
  64.  
  65.         switch (selector){
  66.         case filterSelectorAbout:
  67.                 DoAbout((AboutRecordPtr)pb);
  68.                 break;
  69.         case filterSelectorParameters:
  70. //              dbg("filterSelectorParameters");
  71.                 wantdialog = true; // was: true;
  72.                 break;
  73.         case filterSelectorPrepare:
  74. //              dbg("filterSelectorPrepare");
  75.                 DoPrepare(pb);
  76.                 init_symtab(predefs); // ready for parser calls
  77.                 break;
  78.         case filterSelectorStart:
  79. //              dbg("filterSelectorStart");
  80.                 if(!pb->parameters)
  81.                         pb->parameters = PINEWHANDLE(0);
  82.  
  83.                 checkandinitparams(data,pb->parameters);
  84.  
  85.                 if( wantdialog && (!gdata->standalone || gdata->parm.popDialog) ){
  86.                         if( maindialog(pb) ){
  87.                                 /* update parameters */
  88.                                 saveparams(pb->parameters);
  89.                         }else
  90.                                 e = userCanceledErr;
  91.                         wantdialog = false;
  92.                 }
  93.  
  94.                 if(!e){
  95.                         if(setup(pb)){
  96.                                 DoStart(pb);
  97.                         }else{
  98.                                 SYSBEEP(1);
  99.                                 e = filterBadParameters;
  100.                         }
  101.                 }
  102.                 break;
  103.         case filterSelectorContinue:
  104.                 e = DoContinue(pb);
  105.                 break;
  106.         case filterSelectorFinish:
  107.                 DoFinish(pb);
  108.                 break;
  109.         default:
  110.                 e = filterBadParameters;
  111.         }
  112.                
  113.         *result = e;
  114.  
  115.         ExitCodeResource();
  116. }
  117.  
  118. void checkandinitparams(long *data,Handle params){
  119.         char *reasonstr;
  120.         int i;
  121.         char *reason;
  122.        
  123.         if(!(params && readparams(params,false,&reasonstr))){
  124.                 /* either the parameter handle was uninitialised,
  125.                    or the parameter data couldn't be read; set default values */
  126.  
  127.                 if(readPARMresource(hDllInstance,&reason))
  128.                         gdata->standalone = true;
  129.                 else{
  130.                         /* no scripted parameters - dialog wanted */
  131.                         for(i=0;i<8;++i)
  132.                                 slider[i] = i*10+100;
  133.                         for(i=4;i--;)
  134.                                 expr[i] = my_strdup(defaultexpr[i]);
  135.                 }
  136.         }
  137.                
  138.         if( ! ReadScriptParamsOnRead() )
  139.                 saveparams(gpb->parameters); /* save the scripted params */
  140.  
  141.         /* check for NULL expression pointers (?) */
  142.         for(i=4;i--;)
  143.                 if(!expr[i]) expr[i] = my_strdup(defaultexpr[i]);
  144. }
  145.  
  146. void DoPrepare(FilterRecordPtr pb){
  147.         int i;
  148.  
  149.         for(i=4;i--;){
  150.                 if(expr[i]||tree[i]) DBG("expr[] or tree[] non-NULL in Prepare!");
  151.                 expr[i] = NULL;
  152.                 tree[i] = NULL;
  153.         }
  154. }
  155.  
  156. void RequestNext(FilterRecordPtr pb,long toprow){
  157.         /* Request next block of the image */
  158.  
  159.         pb->inLoPlane = pb->outLoPlane = 0;
  160.         pb->inHiPlane = pb->outHiPlane = nplanes-1;
  161.  
  162.         if(srcradused){
  163.                 SETRECT(pb->inRect,0,0,pb->imageSize.h,pb->imageSize.v);
  164.         }else{
  165.                 pb->inRect.left = pb->filterRect.left;
  166.                 pb->inRect.right = pb->filterRect.right;
  167.                 pb->inRect.top = toprow;
  168.                 pb->inRect.bottom = MIN(toprow + chunksize,pb->filterRect.bottom);
  169.         }
  170.         pb->outRect = pb->inRect;
  171. /*
  172. {char s[0x100];sprintf(s,"RequestNext srcradused=%d inRect=(%d,%d,%d,%d) filterRect=(%d,%d,%d,%d)",
  173.         srcradused,
  174.         pb->inRect.left,pb->inRect.top,pb->inRect.right,pb->inRect.bottom,
  175.         pb->filterRect.left,pb->filterRect.top,pb->filterRect.right,pb->filterRect.bottom);dbg(s);}
  176. */
  177. }
  178.  
  179. void DoStart(FilterRecordPtr pb){
  180. //dbg("DoStart");
  181.         /* if src() or rad() functions are used, random access to the image data is required,
  182.            so we must request the entire image in a single chunk. */
  183.         chunksize = srcradused ? (pb->filterRect.bottom - pb->filterRect.top) : CHUNK_ROWS;
  184.         toprow = pb->filterRect.top;
  185.         RequestNext(pb,toprow);
  186. }
  187.  
  188. OSErr DoContinue(FilterRecordPtr pb){
  189.         OSErr e = noErr;
  190.         Rect *fr = srcradused ? &pb->filterRect : &pb->inRect;
  191.         long outoffset = (long)pb->outRowBytes*(fr->top - pb->outRect.top)
  192.                                          + (long)nplanes*(fr->left - pb->outRect.left);
  193.  
  194. //      {char s[0x100];sprintf(s,"DoContinue: outoffset=%d\n",outoffset);dbg(s);}
  195.        
  196.         if(!(e = process_scaled(pb,true,
  197.                                 &pb->inRect,
  198.                                 fr,
  199.                                 fr,//&pb->outRect,
  200.                                 (Ptr)pb->outData+outoffset,pb->outRowBytes, 1.))){
  201.                 toprow += chunksize;
  202.                 if(toprow < pb->filterRect.bottom)
  203.                         RequestNext(pb,toprow);
  204.                 else{
  205.                         SETRECT(pb->inRect,0,0,0,0);
  206.                         pb->outRect = pb->maskRect = pb->inRect;
  207.                 }
  208.         }
  209.         return e;
  210. }
  211.  
  212. void DoFinish(FilterRecordPtr pb){
  213.         int i;
  214.        
  215.         WriteScriptParamsOnRead();
  216.  
  217.         for(i=4;i--;){
  218.                 freetree(tree[i]);
  219.                 if(expr[i]) free(expr[i]);
  220.         }
  221. }
  222.