Subversion Repositories filter_foundry

Rev

Rev 106 | Rev 118 | 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. #ifdef MAC_ENV
  21.         #include <fp.h>
  22. #endif
  23.  
  24. #include <math.h>
  25. #include <stdlib.h>
  26.  
  27. #ifndef PARSERTEST
  28. #include "ff.h"
  29. #endif
  30. #include "funcs.h"
  31. #include "y.tab.h"
  32.  
  33. #include "node.h" // for symbol "var[]"
  34.  
  35. #define RINT //no rounding for now
  36.  
  37. //#if TARGET_API_MAC_CARBON
  38. // this is another incompatibility between Classic stdclib and OS X stdclib
  39. // ***FIXME: need to access real OS X includes for Carbon build
  40. //#undef RAND_MAX
  41. //#define RAND_MAX    0x7fffffff
  42. //#endif
  43.  
  44. extern value_type slider[],cell[],var[],map[][0x100];
  45. extern unsigned char *image_ptr;
  46.  
  47. /* Channel z for the input pixel at coordinates x,y.
  48.  * Coordinates are relative to the input image data (pb->inData) */
  49. static value_type rawsrc(value_type x,value_type y,value_type z){
  50.         if(x < gpb->inRect.left)
  51.                 x = gpb->inRect.left;
  52.         else if(x >= gpb->inRect.right)
  53.                 x = gpb->inRect.right-1;
  54.         if(y < gpb->inRect.top)
  55.                 y = gpb->inRect.top;
  56.         else if(y >= gpb->inRect.bottom)
  57.                 y = gpb->inRect.bottom-1;
  58.         return ((unsigned char*)gpb->inData)[ (long)gpb->inRowBytes*(y - gpb->inRect.top)
  59.                                                                                   + (long)nplanes*(x - gpb->inRect.left) + z ];
  60. }
  61.  
  62. /* src(x,y,z) Channel z for the pixel at coordinates x,y.
  63.  * Coordinates are relative to filtered area (selection). */
  64. value_type ff_src(value_type x,value_type y,value_type z){
  65. #ifdef PARSERTEST
  66.         return 0;
  67. #else
  68.         if(x < 0)
  69.                 x = 0;
  70.         else if(x >= var['X'])
  71.                 x = var['X']-1;
  72.         if(y < 0)
  73.                 y = 0;
  74.         else if(y >= var['Y'])
  75.                 y = var['Y']-1;
  76.         return z >= 0 && z < var['Z'] ?
  77.                 image_ptr[(long)gpb->inRowBytes*y + (long)nplanes*x + z] : 0;
  78. #endif
  79. }
  80.  
  81. /* rad(d,m,z) Channel z in the source image, which is m units away,
  82.         at an angle of d, from the center of the image */
  83. value_type ff_rad(value_type d,value_type m,value_type z){
  84.         return ff_src(ff_r2x(d,m) + var['X']/2, ff_r2y(d,m) + var['Y']/2, z);
  85. }
  86.  
  87. /* ctl(i) Value of slider i, where i is an integer between 0 and 7, inclusive */
  88. value_type ff_ctl(value_type i){
  89.         return i>=0 && i<=7 ? slider[i] : 0;
  90. }
  91.  
  92. /* val(i,a,b) Value of slider i, mapped onto the range a to b */
  93. value_type ff_val(value_type i,value_type a,value_type b){
  94.         return ((long)ff_ctl(i)*(b-a))/255 + a;
  95. }
  96.  
  97. /* map(i,n) Item n from mapping table i, where i is an integer between
  98.         0 and 3, inclusive, and n is and integer between 0 and 255,
  99.         inclusive */
  100. value_type ff_map(value_type i,value_type n){
  101. /*
  102.         if( i>=0 && i<=3 && n>=0 && n<=255 ){
  103.                 int H = slider[i*2],L = slider[i*2+1];
  104.                 return n<=L || H==L ? 0 : ( n>=H ? 255 : ((n-L)*255L)/(H-L) );
  105.         }else
  106.                 return 0;
  107. */
  108.         // this code is from GIMP User Filter
  109.         value_type x = ff_ctl(i*2),
  110.                            y = ff_ctl(i*2+1);
  111.         return abs(((long)n*(y-x) / 255)+x);
  112. }
  113.  
  114. /* min(a,b) Lesser of a and b */
  115. value_type ff_min(value_type a,value_type b){
  116.         return a < b ? a : b;
  117. }
  118.  
  119. /* max(a,b) Greater of a and b */
  120. value_type ff_max(value_type a,value_type b){
  121.         return a > b ? a : b;
  122. }
  123.  
  124. /* abs(a) Absolute value of a */
  125. value_type ff_abs(value_type a){
  126.         return abs(a);
  127. }
  128.  
  129. /* add(a,b,c) Sum of a and b, or c, whichever is lesser */
  130. value_type ff_add(value_type a,value_type b,value_type c){
  131.         return ff_min(a+b,c);
  132. }
  133.  
  134. /* sub(a,b,c) Difference of a and b, or c, whichever is greater */
  135. value_type ff_sub(value_type a,value_type b,value_type c){
  136.         return ff_max(ff_dif(a,b),c);
  137. }
  138.  
  139. /* dif(a,b) Absolute value of the difference of a and b */
  140. value_type ff_dif(value_type a,value_type b){
  141.         return abs(a-b);
  142. }
  143.  
  144. /* rnd(a,b) Random number between a and b, inclusive */
  145. value_type ff_rnd(value_type a,value_type b){
  146.         return (int)((abs(a-b)+1)*(rand()/(RAND_MAX+1.))) + ff_min(a,b);
  147. //      return ((unsigned)rand() % (ff_dif(a,b)+1)) + ff_min(a,b);
  148. }
  149.  
  150. /* mix(a,b,n,d) Mixture of a and b by fraction n/d, a*n/d+b*(d-n)/d */
  151. value_type ff_mix(value_type a,value_type b,value_type n,value_type d){
  152.         return d ? ((long)a*n)/d + ((long)b*(d-n))/d : 0;
  153. }
  154.  
  155. /* scl(a,il,ih,ol,oh) Scale a from input range (il to ih)
  156.                       to output range (ol to oh) */
  157. value_type ff_scl(value_type a,value_type il,value_type ih,
  158.                                   value_type ol,value_type oh){
  159.         return ih==il ? 0 : ol + ((long)(oh-ol)*(a-il))/(ih-il);
  160. }
  161.  
  162. /* adapted from http://remus.rutgers.edu/~rhoads/Code/isqrt.c */
  163. /* also see http://www.freaknet.org/martin/tape/gos/misc/personal/msc/sqrt/sqrt.c */
  164. #define NBITS (sizeof(long)*8)
  165. #define TOP2BITS(x) (x>>(NBITS-2))
  166.  
  167. unsigned long isqrt (unsigned long x)
  168. {
  169.     unsigned i;
  170.     unsigned long a = 0, e = 0, r = 0;
  171.  
  172.  
  173.     for (i=0; i < (NBITS >> 1); i++)
  174.         {
  175.         r <<= 2;
  176.         r +=  TOP2BITS(x);
  177.         x <<= 2;
  178.  
  179.         a <<= 1;
  180.         e  =  (a<<1) | 1;
  181.  
  182.         if (r >= e)
  183.             {
  184.             r -= e;
  185.             a++;
  186.             }
  187.         }
  188.  
  189.     return a;
  190. }
  191.  
  192. /* sqr(x) Square root of x */
  193. value_type ff_sqr(value_type x){
  194.         return x < 0 ? 0 : isqrt(x);
  195. }
  196.  
  197. /* sin(x) Sine function of x, where x is an integer between 0 and
  198.         1024, inclusive, and the value returned is an integer
  199.         between -512 and 512, inclusive (Windows) or -1024 and
  200.         1024, inclusive (Mac OS) */
  201. value_type ff_sin(value_type x){
  202.         return ff_cos(x-256); //RINT(TRIGAMP*sin(FFANGLE(x)));
  203. }
  204.  
  205. /* cos(x) Cosine function of x */
  206. value_type ff_cos(value_type x){
  207.         return costab[abs(x) % COSTABSIZE]; //RINT(TRIGAMP*cos(FFANGLE(x)));
  208. }
  209.  
  210. /* tan(x)
  211.         Bounded tangent function of x, where x is an integer
  212.         between -256 and 256, inclusive, and the value returned is
  213.          */
  214. value_type ff_tan(value_type x){
  215.         return tantab[(x+256) % TANTABSIZE]; //RINT(TRIGAMP*tan(FFANGLE(x)));
  216. }
  217.  
  218. /* r2x(d,m) x displacement of the pixel m units away, at an angle of d,
  219.    from an arbitrary center */
  220. value_type ff_r2x(value_type d,value_type m){
  221.         return RINT(m*cos(FFANGLE(d)));
  222. }
  223.  
  224. /* r2y(d,m) y displacement of the pixel m units away, at an angle of d,
  225.    from an arbitrary center */
  226. value_type ff_r2y(value_type d,value_type m){
  227.         return RINT(m*sin(FFANGLE(d)));
  228. }
  229.  
  230. /* c2d(x,y) Angle displacement of the pixel at coordinates x,y */
  231. /* note, sign of y difference is negated, as we are dealing with top-down coordinates
  232.    angle is "observed" */
  233. value_type ff_c2d(value_type x,value_type y){
  234.         return RINT(TO_FFANGLE(atan2(-y,-x))); /* FIXME: why must we negate x here? */
  235. }
  236.  
  237. /* c2m(x,y) Magnitude displacement of the pixel at coordinates x,y */
  238. value_type ff_c2m(value_type x,value_type y){
  239.         return isqrt((long)x*x + (long)y*y);
  240. }
  241.  
  242. /* get(i) Returns the current cell value at i */
  243. value_type ff_get(value_type i){
  244.         return i>=0 && i<=0xff ? cell[i] : 0;
  245. }
  246.  
  247. /* put(v,i) Puts the new value v into cell i */
  248. value_type ff_put(value_type v,value_type i){
  249.         if(i>=0 && i<=0xff)
  250.                 cell[i] = v;
  251.         return v;
  252. }
  253.  
  254. value_type ff_cnv(value_type m11,value_type m12,value_type m13,
  255.                                   value_type m21,value_type m22,value_type m23,
  256.                                   value_type m31,value_type m32,value_type m33,
  257.                                   value_type d)
  258. {
  259. #ifdef PARSERTEST
  260.         return 0;
  261. #else
  262.         long total;
  263.         // shift x,y from selection-relative to image relative
  264.         int x = var['x'] + gpb->filterRect.left,
  265.                 y = var['y'] + gpb->filterRect.top,
  266.                 z = var['z'];
  267.  
  268.         if(z >= 0 && z < var['Z'])
  269.                 total = m11*rawsrc(x-1,y-1,z) + m12*rawsrc(x,y-1,z) + m13*rawsrc(x+1,y-1,z)
  270.                           + m21*rawsrc(x-1,y,  z) + m22*rawsrc(x,y,  z) + m23*rawsrc(x+1,y,  z)
  271.                           + m31*rawsrc(x-1,y+1,z) + m32*rawsrc(x,y+1,z) + m33*rawsrc(x+1,y+1,z);
  272.         else
  273.                 total = 0;
  274.  
  275.         return d ? total/d : 0;
  276. #endif
  277. }
  278.  
  279. /* rst(i) sets a random seed and returns 0. (undocumented Filter Factory function).
  280.    Added by DM, 18 Dec 2018 */
  281. value_type ff_rst(value_type seed){
  282.         srand(seed);
  283.         return 0;
  284. }
  285.  
  286. value_type zero_val = 0;
  287. value_type one_val = 0;
  288. value_type max_channel_val = 255;
  289.  
  290. /* predefined symbols */
  291. struct sym_rec predefs[]={
  292.         /* functions */
  293.  
  294.         {0,TOK_FN3,"src", (pfunc_type)ff_src, 0},
  295.         {0,TOK_FN3,"rad", (pfunc_type)ff_rad, 0},
  296.         {0,TOK_FN1,"ctl", (pfunc_type)ff_ctl, 0},
  297.         {0,TOK_FN3,"val", (pfunc_type)ff_val, 0},
  298.         {0,TOK_FN2,"map", (pfunc_type)ff_map, 0},
  299.         {0,TOK_FN2,"min", (pfunc_type)ff_min, 0},
  300.         {0,TOK_FN2,"max", (pfunc_type)ff_max, 0},
  301.         {0,TOK_FN1,"abs", (pfunc_type)ff_abs, 0},
  302.         {0,TOK_FN3,"add", (pfunc_type)ff_add, 0},
  303.         {0,TOK_FN3,"sub", (pfunc_type)ff_sub, 0},
  304.         {0,TOK_FN2,"dif", (pfunc_type)ff_dif, 0},
  305.         {0,TOK_FN2,"rnd", (pfunc_type)ff_rnd, 0},
  306.         {0,TOK_FN4,"mix", (pfunc_type)ff_mix, 0},
  307.         {0,TOK_FN5,"scl", (pfunc_type)ff_scl, 0},
  308.         {0,TOK_FN1,"sqr", (pfunc_type)ff_sqr, 0},
  309.         {0,TOK_FN1,"sin", (pfunc_type)ff_sin, 0},
  310.         {0,TOK_FN1,"cos", (pfunc_type)ff_cos, 0},
  311.         {0,TOK_FN1,"tan", (pfunc_type)ff_tan, 0},
  312.         {0,TOK_FN2,"r2x", (pfunc_type)ff_r2x, 0},
  313.         {0,TOK_FN2,"r2y", (pfunc_type)ff_r2y, 0},
  314.         {0,TOK_FN2,"c2d", (pfunc_type)ff_c2d, 0},
  315.         {0,TOK_FN2,"c2m", (pfunc_type)ff_c2m, 0},
  316.         {0,TOK_FN1,"get", (pfunc_type)ff_get, 0},
  317.         {0,TOK_FN2,"put", (pfunc_type)ff_put, 0},
  318.         {0,TOK_FN10,"cnv",(pfunc_type)ff_cnv, 0},
  319.         {0,TOK_FN1,"rst", (pfunc_type)ff_rst, 0}, // undocumented FilterFactory function
  320.  
  321.         /* predefined variables (names with more than 1 character); most of them are undocumented in FilterFactory */
  322.         /* the predefined variables with 1 character are defined in lexer.l and process.c */
  323.         /* in this table, you must not add TOK_VAR with only 1 character (since this case is not defined in parser.y) */
  324.  
  325.         {0,TOK_VAR,"rmax",0, &max_channel_val}, // alias of 'R' (defined in lexer.l, line 129)
  326.         {0,TOK_VAR,"gmax",0, &max_channel_val}, // alias of 'G' (defined in lexer.l, line 129)
  327.         {0,TOK_VAR,"bmax",0, &max_channel_val}, // alias of 'B' (defined in lexer.l, line 129)
  328.         {0,TOK_VAR,"amax",0, &max_channel_val}, // alias of 'A' (defined in lexer.l, line 129)
  329.         {0,TOK_VAR,"cmax",0, &max_channel_val}, // alias of 'C' (defined in lexer.l, line 129)
  330.         {0,TOK_VAR,"imax",0, &max_channel_val}, // alias of 'I' (defined in lexer.l, line 129)
  331.         {0,TOK_VAR,"umax",0, &max_channel_val}, // alias of 'U' (defined in lexer.l, line 129)
  332.         {0,TOK_VAR,"vmax",0, &max_channel_val}, // alias of 'V' (defined in lexer.l, line 129)
  333.         {0,TOK_VAR,"dmax",0, &var['D']},
  334.         {0,TOK_VAR,"mmax",0, &var['M']},
  335.         {0,TOK_VAR,"pmax",0, &var['Z']},
  336.         {0,TOK_VAR,"xmax",0, &var['X']},
  337.         {0,TOK_VAR,"ymax",0, &var['Y']},
  338.         {0,TOK_VAR,"zmax",0, &var['Z']},
  339.  
  340.         {0,TOK_VAR,"rmin",0, &zero_val},
  341.         {0,TOK_VAR,"gmin",0, &zero_val},
  342.         {0,TOK_VAR,"bmin",0, &zero_val},
  343.         {0,TOK_VAR,"amin",0, &zero_val},
  344.         {0,TOK_VAR,"cmin",0, &zero_val},
  345.         {0,TOK_VAR,"imin",0, &zero_val},
  346.         {0,TOK_VAR,"umin",0, &zero_val},
  347.         {0,TOK_VAR,"vmin",0, &zero_val},
  348.         {0,TOK_VAR,"dmin",0, &zero_val},
  349.         {0,TOK_VAR,"mmin",0, &zero_val},
  350.         {0,TOK_VAR,"pmin",0, &zero_val},
  351.         {0,TOK_VAR,"xmin",0, &zero_val},
  352.         {0,TOK_VAR,"ymin",0, &zero_val},
  353.         {0,TOK_VAR,"zmin",0, &zero_val},
  354.  
  355.         /* Undocumented synonyms of FilterFactory for compatibility with Premiere */
  356.         {0,TOK_FN10,"cnv0",(pfunc_type)ff_cnv, 0},
  357.         {0,TOK_FN3,"src0", (pfunc_type)ff_src, 0},
  358.         {0,TOK_FN3,"rad0", (pfunc_type)ff_rad, 0},
  359.         {0,TOK_FN10,"cnv1",(pfunc_type)ff_cnv, 0},
  360.         {0,TOK_FN3,"src1", (pfunc_type)ff_src, 0},
  361.         {0,TOK_FN3,"rad1", (pfunc_type)ff_rad, 0},
  362.         {0,TOK_VAR,"r0",0, &var['r']},
  363.         {0,TOK_VAR,"g0",0, &var['g']},
  364.         {0,TOK_VAR,"b0",0, &var['b']},
  365.         {0,TOK_VAR,"a0",0, &var['a']},
  366.         {0,TOK_VAR,"c0",0, &var['c']},
  367.         {0,TOK_VAR,"i0",0, &var['i']},
  368.         {0,TOK_VAR,"u0",0, &var['u']},
  369.         {0,TOK_VAR,"v0",0, &var['v']},
  370.         {0,TOK_VAR,"d0",0, &var['d']},
  371.         {0,TOK_VAR,"m0",0, &var['m']},
  372.         {0,TOK_VAR,"r1",0, &var['r']},
  373.         {0,TOK_VAR,"g1",0, &var['g']},
  374.         {0,TOK_VAR,"b1",0, &var['b']},
  375.         {0,TOK_VAR,"a1",0, &var['a']},
  376.         {0,TOK_VAR,"c1",0, &var['c']},
  377.         {0,TOK_VAR,"i1",0, &var['i']},
  378.         {0,TOK_VAR,"u1",0, &var['u']},
  379.         {0,TOK_VAR,"v1",0, &var['v']},
  380.         {0,TOK_VAR,"d1",0, &var['d']},
  381.         {0,TOK_VAR,"m1",0, &var['m']},
  382.         {0,TOK_VAR,"tmin",0, &zero_val},
  383.         {0,TOK_VAR,"tmax",0, &one_val},
  384.         {0,TOK_VAR,"total",0, &one_val},
  385.  
  386.         {0,0,0,0,0}
  387. };