Subversion Repositories filter_foundry

Rev

Rev 89 | Rev 102 | 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-7 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,cnvused,chunksize,toprow;
  32. value_type slider[8],cell[0x100],map[4][0x100];
  33. char *expr[4];
  34. long maxSpace;
  35. globals_t *gdata;
  36. FilterRecordPtr gpb;
  37.  
  38. #ifdef MAC_ENV
  39.         #define hDllInstance NULL /* fake this Windows-only global */
  40. #endif
  41.  
  42. extern struct sym_rec predefs[];
  43. extern int nplanes,varused[];
  44.  
  45. int checkandinitparams(Handle params);
  46.  
  47. DLLEXPORT MACPASCAL
  48. void ENTRYPOINT(short selector,FilterRecordPtr pb,long *data,short *result){
  49.         static Boolean wantdialog = false;
  50.         OSErr e = noErr;
  51.         char *reason;
  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.                 if(!gdata->parmloaded)
  68.                         gdata->standalone = gdata->parmloaded = readPARMresource(hDllInstance,&reason,1);
  69.                 DoAbout((AboutRecordPtr)pb);
  70.                 break;
  71.         case filterSelectorParameters:
  72.                 wantdialog = true;
  73.                 break;
  74.         case filterSelectorPrepare:
  75.                 DoPrepare(pb);
  76.                 init_symtab(predefs); // ready for parser calls
  77.                 break;
  78.         case filterSelectorStart:
  79.                 /* initialise the parameter handle that Photoshop keeps for us */
  80.                 if(!pb->parameters)
  81.                         pb->parameters = PINEWHANDLE(0);
  82.  
  83.                 wantdialog |= checkandinitparams(pb->parameters);
  84.  
  85.                 /* wantdialog = false means that we never got a Parameters call, so we're not supposed to ask user */
  86.                 if( wantdialog && (!gdata->standalone || gdata->parm.popDialog) ){
  87.                         if( maindialog(pb) ){
  88.                                 /* update stored parameters from new user settings */
  89.                                 saveparams(pb->parameters);
  90.                         }else
  91.                                 e = userCanceledErr;
  92.                 }
  93.                 wantdialog = false;
  94.  
  95.                 if(!e){
  96.                         if(setup(pb)){
  97.                                 DoStart(pb);
  98.                         }else{
  99.                                 SYSBEEP(1);
  100.                                 e = filterBadParameters;
  101.                         }
  102.                 }
  103.                 break;
  104.         case filterSelectorContinue:
  105.                 e = DoContinue(pb);
  106.                 break;
  107.         case filterSelectorFinish:
  108.                 DoFinish(pb);
  109.                 break;
  110.         default:
  111.                 e = filterBadParameters;
  112.         }
  113.                
  114.         *result = e;
  115.  
  116.         ExitCodeResource();
  117. }
  118.  
  119. int checkandinitparams(Handle params){
  120.         char *reasonstr,*reason;
  121.         int i,f,showdialog;
  122.        
  123.         if( (f = !(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.                 // see if saved parameters exist
  128.                 gdata->standalone = gdata->parmloaded = readPARMresource(hDllInstance,&reason,1);
  129.  
  130.                 if(!gdata->standalone){
  131.                         // no saved settings (not standalone)
  132.                         for(i = 0; i < 8; ++i)
  133.                                 slider[i] = i*10+100;
  134.                         if(gpb->imageMode == plugInModeRGBColor){
  135.                                 expr[0] = my_strdup("r");
  136.                                 expr[1] = my_strdup("g");
  137.                                 expr[2] = my_strdup("b");
  138.                                 expr[3] = my_strdup("a");
  139.                         }else{
  140.                                 expr[0] = my_strdup("c");
  141.                                 expr[1] = my_strdup("c");
  142.                                 expr[2] = my_strdup("c");
  143.                                 expr[3] = my_strdup("c");
  144.                         }
  145.                 }
  146.         }
  147.        
  148.         // let scripting system change parameters, if we're scripted;
  149.         // user may want to force display of dialog during scripting playback
  150.         showdialog = ReadScriptParamsOnRead();
  151.  
  152.         saveparams(params);
  153.         return f || showdialog;
  154. }
  155.  
  156. void DoPrepare(FilterRecordPtr pb){
  157.         int i;
  158.  
  159.         for(i = 4; i--;){
  160.                 if(expr[i]||tree[i]) DBG("expr[] or tree[] non-NULL in Prepare!");
  161.                 expr[i] = NULL;
  162.                 tree[i] = NULL;
  163.         }
  164.         maxSpace = pb->maxSpace;
  165. }
  166.  
  167. void RequestNext(FilterRecordPtr pb,long toprow){
  168.         /* Request next block of the image */
  169.  
  170.         pb->inLoPlane = pb->outLoPlane = 0;
  171.         pb->inHiPlane = pb->outHiPlane = nplanes-1;
  172.  
  173.         // if any of the formulae involve random access to image pixels,
  174.         // ask for the entire image
  175.         if(needall){
  176.                 SETRECT(pb->inRect,0,0,pb->imageSize.h,pb->imageSize.v);
  177.         }else{
  178.                 // otherwise, process the filtered area, by chunksize parts
  179.                 pb->inRect.left = pb->filterRect.left;
  180.                 pb->inRect.right = pb->filterRect.right;
  181.                 pb->inRect.top = toprow;
  182.                 pb->inRect.bottom = MIN(toprow + chunksize,pb->filterRect.bottom);
  183.                
  184.                 if(cnvused){
  185.                         // cnv() needs one extra pixel in each direction
  186.                         if(pb->inRect.left > 0)
  187.                                 --pb->inRect.left;
  188.                         if(pb->inRect.right < pb->imageSize.h)
  189.                                 ++pb->inRect.right;
  190.                         if(pb->inRect.top > 0)
  191.                                 --pb->inRect.top;
  192.                         if(pb->inRect.bottom < pb->imageSize.v)
  193.                                 ++pb->inRect.bottom;
  194.                 }
  195.         }
  196.         pb->outRect = pb->filterRect;
  197. /*
  198. {char s[0x100];sprintf(s,"RequestNext needall=%d inRect=(%d,%d,%d,%d) filterRect=(%d,%d,%d,%d)",
  199.         needall,
  200.         pb->inRect.left,pb->inRect.top,pb->inRect.right,pb->inRect.bottom,
  201.         pb->filterRect.left,pb->filterRect.top,pb->filterRect.right,pb->filterRect.bottom);dbg(s);}
  202. */
  203. }
  204.  
  205. void DoStart(FilterRecordPtr pb){
  206. //dbg("DoStart");
  207.         /* if src() or rad() functions are used, random access to the image data is required,
  208.            so we must request the entire image in a single chunk. */
  209.         chunksize = needall ? (pb->filterRect.bottom - pb->filterRect.top) : CHUNK_ROWS;
  210.         toprow = pb->filterRect.top;
  211.         RequestNext(pb,toprow);
  212. }
  213.  
  214. OSErr DoContinue(FilterRecordPtr pb){
  215.         OSErr e = noErr;
  216.         Rect fr;
  217.         long outoffset;
  218.  
  219.         if(needall)
  220.                 fr = pb->filterRect;  // filter whole selection at once
  221.         else if(cnvused){
  222.                 // we've requested one pixel extra all around
  223.                 // (see RequestNext()), just for access purposes. But filter
  224.                 // original selection only.
  225.                 fr.left = pb->filterRect.left;
  226.                 fr.right = pb->filterRect.right;
  227.                 fr.top = toprow;
  228.                 fr.bottom = MIN(toprow + chunksize,pb->filterRect.bottom);
  229.         }else  // filter whatever portion we've been given
  230.                 fr = pb->inRect;
  231.  
  232.         outoffset = (long)pb->outRowBytes*(fr.top - pb->outRect.top)
  233.                                 + (long)nplanes*(fr.left - pb->outRect.left);
  234.  
  235.         if(!(e = process_scaled(pb, true, &fr, &fr,
  236.                                 (Ptr)pb->outData+outoffset, pb->outRowBytes, 1.)))
  237.         {
  238.                 toprow += chunksize;
  239.                 if(toprow < pb->filterRect.bottom)
  240.                         RequestNext(pb,toprow);
  241.                 else{
  242.                         SETRECT(pb->inRect,0,0,0,0);
  243.                         pb->outRect = pb->maskRect = pb->inRect;
  244.                 }
  245.         }
  246.         return e;
  247. }
  248.  
  249. void DoFinish(FilterRecordPtr pb){
  250.         int i;
  251.  
  252.         WriteScriptParamsOnRead();
  253.  
  254.         for(i = 4; i--;){
  255.                 freetree(tree[i]);
  256.                 if(expr[i]) free(expr[i]);
  257.         }
  258. }
  259.