Subversion Repositories filter_foundry

Rev

Rev 79 | Rev 117 | 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. #define RINT //no rounding for now
  34.  
  35. //#if TARGET_API_MAC_CARBON
  36. // this is another incompatibility between Classic stdclib and OS X stdclib
  37. // ***FIXME: need to access real OS X includes for Carbon build
  38. //#undef RAND_MAX
  39. //#define RAND_MAX    0x7fffffff
  40. //#endif
  41.  
  42. extern value_type slider[],cell[],var[],map[][0x100];
  43. extern unsigned char *image_ptr;
  44.  
  45. /* Channel z for the input pixel at coordinates x,y.
  46.  * Coordinates are relative to the input image data (pb->inData) */
  47. static value_type rawsrc(value_type x,value_type y,value_type z){
  48.         if(x < gpb->inRect.left)
  49.                 x = gpb->inRect.left;
  50.         else if(x >= gpb->inRect.right)
  51.                 x = gpb->inRect.right-1;
  52.         if(y < gpb->inRect.top)
  53.                 y = gpb->inRect.top;
  54.         else if(y >= gpb->inRect.bottom)
  55.                 y = gpb->inRect.bottom-1;
  56.         return ((unsigned char*)gpb->inData)[ (long)gpb->inRowBytes*(y - gpb->inRect.top)
  57.                                                                                   + (long)nplanes*(x - gpb->inRect.left) + z ];
  58. }
  59.  
  60. /* src(x,y,z) Channel z for the pixel at coordinates x,y.
  61.  * Coordinates are relative to filtered area (selection). */
  62. value_type ff_src(value_type x,value_type y,value_type z){
  63. #ifdef PARSERTEST
  64.         return 0;
  65. #else
  66.         if(x < 0)
  67.                 x = 0;
  68.         else if(x >= var['X'])
  69.                 x = var['X']-1;
  70.         if(y < 0)
  71.                 y = 0;
  72.         else if(y >= var['Y'])
  73.                 y = var['Y']-1;
  74.         return z >= 0 && z < var['Z'] ?
  75.                 image_ptr[(long)gpb->inRowBytes*y + (long)nplanes*x + z] : 0;
  76. #endif
  77. }
  78.  
  79. /* rad(d,m,z) Channel z in the source image, which is m units away,
  80.         at an angle of d, from the center of the image */
  81. value_type ff_rad(value_type d,value_type m,value_type z){
  82.         return ff_src(ff_r2x(d,m) + var['X']/2, ff_r2y(d,m) + var['Y']/2, z);
  83. }
  84.  
  85. /* ctl(i) Value of slider i, where i is an integer between 0 and 7, inclusive */
  86. value_type ff_ctl(value_type i){
  87.         return i>=0 && i<=7 ? slider[i] : 0;
  88. }
  89.  
  90. /* val(i,a,b) Value of slider i, mapped onto the range a to b */
  91. value_type ff_val(value_type i,value_type a,value_type b){
  92.         return ((long)ff_ctl(i)*(b-a))/255 + a;
  93. }
  94.  
  95. /* map(i,n) Item n from mapping table i, where i is an integer between
  96.         0 and 3, inclusive, and n is and integer between 0 and 255,
  97.         inclusive */
  98. value_type ff_map(value_type i,value_type n){
  99. /*
  100.         if( i>=0 && i<=3 && n>=0 && n<=255 ){
  101.                 int H = slider[i*2],L = slider[i*2+1];
  102.                 return n<=L || H==L ? 0 : ( n>=H ? 255 : ((n-L)*255L)/(H-L) );
  103.         }else
  104.                 return 0;
  105. */
  106.         // this code is from GIMP User Filter
  107.         value_type x = ff_ctl(i*2),
  108.                            y = ff_ctl(i*2+1);
  109.         return abs(((long)n*(y-x) / 255)+x);
  110. }
  111.  
  112. /* min(a,b) Lesser of a and b */
  113. value_type ff_min(value_type a,value_type b){
  114.         return a < b ? a : b;
  115. }
  116.  
  117. /* max(a,b) Greater of a and b */
  118. value_type ff_max(value_type a,value_type b){
  119.         return a > b ? a : b;
  120. }
  121.  
  122. /* abs(a) Absolute value of a */
  123. value_type ff_abs(value_type a){
  124.         return abs(a);
  125. }
  126.  
  127. /* add(a,b,c) Sum of a and b, or c, whichever is lesser */
  128. value_type ff_add(value_type a,value_type b,value_type c){
  129.         return ff_min(a+b,c);
  130. }
  131.  
  132. /* sub(a,b,c) Difference of a and b, or c, whichever is greater */
  133. value_type ff_sub(value_type a,value_type b,value_type c){
  134.         return ff_max(ff_dif(a,b),c);
  135. }
  136.  
  137. /* dif(a,b) Absolute value of the difference of a and b */
  138. value_type ff_dif(value_type a,value_type b){
  139.         return abs(a-b);
  140. }
  141.  
  142. /* rnd(a,b) Random number between a and b, inclusive */
  143. value_type ff_rnd(value_type a,value_type b){
  144.         return (int)((abs(a-b)+1)*(rand()/(RAND_MAX+1.))) + ff_min(a,b);
  145. //      return ((unsigned)rand() % (ff_dif(a,b)+1)) + ff_min(a,b);
  146. }
  147.  
  148. /* mix(a,b,n,d) Mixture of a and b by fraction n/d, a*n/d+b*(d-n)/d */
  149. value_type ff_mix(value_type a,value_type b,value_type n,value_type d){
  150.         return d ? ((long)a*n)/d + ((long)b*(d-n))/d : 0;
  151. }
  152.  
  153. /* scl(a,il,ih,ol,oh) Scale a from input range (il to ih)
  154.                       to output range (ol to oh) */
  155. value_type ff_scl(value_type a,value_type il,value_type ih,
  156.                                   value_type ol,value_type oh){
  157.         return ih==il ? 0 : ol + ((long)(oh-ol)*(a-il))/(ih-il);
  158. }
  159.  
  160. /* adapted from http://remus.rutgers.edu/~rhoads/Code/isqrt.c */
  161. /* also see http://www.freaknet.org/martin/tape/gos/misc/personal/msc/sqrt/sqrt.c */
  162. #define NBITS (sizeof(long)*8)
  163. #define TOP2BITS(x) (x>>(NBITS-2))
  164.  
  165. unsigned long isqrt (unsigned long x)
  166. {
  167.     unsigned i;
  168.     unsigned long a = 0, e = 0, r = 0;
  169.  
  170.  
  171.     for (i=0; i < (NBITS >> 1); i++)
  172.         {
  173.         r <<= 2;
  174.         r +=  TOP2BITS(x);
  175.         x <<= 2;
  176.  
  177.         a <<= 1;
  178.         e  =  (a<<1) | 1;
  179.  
  180.         if (r >= e)
  181.             {
  182.             r -= e;
  183.             a++;
  184.             }
  185.         }
  186.  
  187.     return a;
  188. }
  189.  
  190. /* sqr(x) Square root of x */
  191. value_type ff_sqr(value_type x){
  192.         return x < 0 ? 0 : isqrt(x);
  193. }
  194.  
  195. /* sin(x) Sine function of x, where x is an integer between 0 and
  196.         1024, inclusive, and the value returned is an integer
  197.         between -512 and 512, inclusive (Windows) or -1024 and
  198.         1024, inclusive (Mac OS) */
  199. value_type ff_sin(value_type x){
  200.         return ff_cos(x-256); //RINT(TRIGAMP*sin(FFANGLE(x)));
  201. }
  202.  
  203. /* cos(x) Cosine function of x */
  204. value_type ff_cos(value_type x){
  205.         return costab[abs(x) % COSTABSIZE]; //RINT(TRIGAMP*cos(FFANGLE(x)));
  206. }
  207.  
  208. /* tan(x)
  209.         Bounded tangent function of x, where x is an integer
  210.         between -256 and 256, inclusive, and the value returned is
  211.          */
  212. value_type ff_tan(value_type x){
  213.         return tantab[(x+256) % TANTABSIZE]; //RINT(TRIGAMP*tan(FFANGLE(x)));
  214. }
  215.  
  216. /* r2x(d,m) x displacement of the pixel m units away, at an angle of d,
  217.    from an arbitrary center */
  218. value_type ff_r2x(value_type d,value_type m){
  219.         return RINT(m*cos(FFANGLE(d)));
  220. }
  221.  
  222. /* r2y(d,m) y displacement of the pixel m units away, at an angle of d,
  223.    from an arbitrary center */
  224. value_type ff_r2y(value_type d,value_type m){
  225.         return RINT(m*sin(FFANGLE(d)));
  226. }
  227.  
  228. /* c2d(x,y) Angle displacement of the pixel at coordinates x,y */
  229. /* note, sign of y difference is negated, as we are dealing with top-down coordinates
  230.    angle is "observed" */
  231. value_type ff_c2d(value_type x,value_type y){
  232.         return RINT(TO_FFANGLE(atan2(-y,-x))); /* FIXME: why must we negate x here? */
  233. }
  234.  
  235. /* c2m(x,y) Magnitude displacement of the pixel at coordinates x,y */
  236. value_type ff_c2m(value_type x,value_type y){
  237.         return isqrt((long)x*x + (long)y*y);
  238. }
  239.  
  240. /* get(i) Returns the current cell value at i */
  241. value_type ff_get(value_type i){
  242.         return i>=0 && i<=0xff ? cell[i] : 0;
  243. }
  244.  
  245. /* put(v,i) Puts the new value v into cell i */
  246. value_type ff_put(value_type v,value_type i){
  247.         if(i>=0 && i<=0xff)
  248.                 cell[i] = v;
  249.         return v;
  250. }
  251.  
  252. value_type ff_cnv(value_type m11,value_type m12,value_type m13,
  253.                                   value_type m21,value_type m22,value_type m23,
  254.                                   value_type m31,value_type m32,value_type m33,
  255.                                   value_type d)
  256. {
  257. #ifdef PARSERTEST
  258.         return 0;
  259. #else
  260.         long total;
  261.         // shift x,y from selection-relative to image relative
  262.         int x = var['x'] + gpb->filterRect.left,
  263.                 y = var['y'] + gpb->filterRect.top,
  264.                 z = var['z'];
  265.  
  266.         if(z >= 0 && z < var['Z'])
  267.                 total = m11*rawsrc(x-1,y-1,z) + m12*rawsrc(x,y-1,z) + m13*rawsrc(x+1,y-1,z)
  268.                           + m21*rawsrc(x-1,y,  z) + m22*rawsrc(x,y,  z) + m23*rawsrc(x+1,y,  z)
  269.                           + m31*rawsrc(x-1,y+1,z) + m32*rawsrc(x,y+1,z) + m33*rawsrc(x+1,y+1,z);
  270.         else
  271.                 total = 0;
  272.  
  273.         return d ? total/d : 0;
  274. #endif
  275. }
  276.  
  277. /* rst(i) sets a random seed and returns 0. (undocumented Filter Factory function).
  278.    Added by DM, 18 Dec 2018 */
  279. value_type ff_rst(value_type seed){
  280.         srand(seed);
  281.         return 0;
  282. }
  283.  
  284. value_type zero_val = 0;
  285.  
  286. /* predefined symbols */
  287. struct sym_rec predefs[]={
  288.         /* functions */
  289.         {0,TOK_FN3,"src", (pfunc_type)ff_src, 0},
  290.         {0,TOK_FN3,"rad", (pfunc_type)ff_rad, 0},
  291.         {0,TOK_FN1,"ctl", (pfunc_type)ff_ctl, 0},
  292.         {0,TOK_FN3,"val", (pfunc_type)ff_val, 0},
  293.         {0,TOK_FN2,"map", (pfunc_type)ff_map, 0},
  294.         {0,TOK_FN2,"min", (pfunc_type)ff_min, 0},
  295.         {0,TOK_FN2,"max", (pfunc_type)ff_max, 0},
  296.         {0,TOK_FN1,"abs", (pfunc_type)ff_abs, 0},
  297.         {0,TOK_FN3,"add", (pfunc_type)ff_add, 0},
  298.         {0,TOK_FN3,"sub", (pfunc_type)ff_sub, 0},
  299.         {0,TOK_FN2,"dif", (pfunc_type)ff_dif, 0},
  300.         {0,TOK_FN2,"rnd", (pfunc_type)ff_rnd, 0},
  301.         {0,TOK_FN4,"mix", (pfunc_type)ff_mix, 0},
  302.         {0,TOK_FN5,"scl", (pfunc_type)ff_scl, 0},
  303.         {0,TOK_FN1,"sqr", (pfunc_type)ff_sqr, 0},
  304.         {0,TOK_FN1,"sin", (pfunc_type)ff_sin, 0},
  305.         {0,TOK_FN1,"cos", (pfunc_type)ff_cos, 0},
  306.         {0,TOK_FN1,"tan", (pfunc_type)ff_tan, 0},
  307.         {0,TOK_FN2,"r2x", (pfunc_type)ff_r2x, 0},
  308.         {0,TOK_FN2,"r2y", (pfunc_type)ff_r2y, 0},
  309.         {0,TOK_FN2,"c2d", (pfunc_type)ff_c2d, 0},
  310.         {0,TOK_FN2,"c2m", (pfunc_type)ff_c2m, 0},
  311.         {0,TOK_FN1,"get", (pfunc_type)ff_get, 0},
  312.         {0,TOK_FN2,"put", (pfunc_type)ff_put, 0},
  313.         {0,TOK_FN10,"cnv",(pfunc_type)ff_cnv, 0},
  314.         {0,TOK_FN1,"rst", (pfunc_type)ff_rst, 0},
  315.         /* predefined variables (names >1 characters) */
  316.         {0,TOK_VAR,"dmin",0, &zero_val},
  317.         {0,TOK_VAR,"mmin",0, &zero_val},
  318.         {0,0,0,0,0}
  319. };
  320.  
  321.