Filter Source Examples
 
 
****************************************************************
****************************************************************
* Filter source examples
*     part of FilterFormula by ATS/Graphics
*
* (C) 1998 by ATS/Graphics
* these filters are for free use, and may be copied freely, but 
* must not be sold separately (also the filters created by 
* simply compiling them). If they are distributed in a compiled 
* form (as freeware), they must be accompanied by a notice in a 
* text file that they were created by the use of FilterFormula 
* and where it can be obtained (ATS/Graphics homepage).
* The authors do not take any responsibility for the 
* functionality and eventual damages by the use of these
* filters.
****************************************************************
****************************************************************
 
 

****************************************************************
** MOSAIC
****************************************************************
*
* Slider 0: numpoly  .. number of polygons per smaller part 
*                       (higher value..slower)!!
*        1: repeat   .. repetion factor
*
****************************************************************

init {  // set a number of random points
  numpts=ctl(0);
  divs=ctl(1);
  xp=X/divs; xp2=xp/2; 
  yp=Y/divs; yp2=yp/2;
  for(ii=0;ii<numpts;ii++) 
  {
    put(rnd(0,xp),ii);
    put(rnd(0,yp),ii+numpts);
  }
}

// main pass - always get the nearest point and use its color

bestidx=-1; bestnum=xp*xp+yp*yp;
for(ii=0;ii<numpts;ii++)
{
  xc=yc=0;
  xx=(x+xp-get(ii))%xp;        if(xx>xp2) xx-=xp; 
  yy=(y+yp-get(ii+numpts))%yp; if(yy>yp2) yy-=yp; 
  dist=xx*xx+yy*yy;
  if(dist<bestnum) { bestidx=ii; bestnum=dist; }
}

if(bestidx<0) { R=G=B=0; }
else
{
  xx=get(bestidx)+x-(x%xp); 
  if(x-xx>xp2) xx+=xp; else if(xx-x>xp2) xx-=xp;
  yy=get(bestidx+numpts)+y-y%yp; 
  if(y-yy>yp2) yy+=yp; else if(yy-y>yp2) yy-=yp;
  R=src(xx,yy,0);
  G=src(xx,yy,1);
  B=src(xx,yy,2);
}

****************************************************************
** ZOOM
****************************************************************
*  Slider 0: X coordinate of zooming center
*         1: Y coordinate       " 
*         2: zooming range (0..200)
****************************************************************

init {
 xx=val(0,0,X);
 yy=val(1,0,X);
}

dd=c2d(x-xx,y-yy);
mm=c2m(x-xx,y-yy);
ct=val(2,0,200); mc=1+ct/10;
R=G=B=0;
ccc=0;

for(ii=0;ii<ct;ii+=mc)

  mmm=(mm*(100+ii))/100;
  xxx=xx+r2x(dd,mmm);
  yyy=yy+r2y(dd,mmm);
  R+=src(xxx,yyy,0);
  G+=src(xxx,yyy,1);
  B+=src(xxx,yyy,2);
  ccc++;
}
R/=ccc;
G/=ccc;
B/=ccc;

****************************************************************
** STRUCTURED GLASS
****************************************************************
*  Slider 0: radius of random error
****************************************************************

xx=rnd(-ctl(0),ctl(0));
yy=rnd(-ctl(0),ctl(0));
R=dr(xx,yy);
G=dg(xx,yy);
B=db(xx,yy);
 

****************************************************************
** ENHANCE PICTURE CONTRAST
****************************************************************
*  Slider 0: cutoff value (? % of all images will be set to 
*            black or white by contrast increase
****************************************************************

init { for(ii=0;ii<256;ii++) put(0,ii); count=0;  }

pass1 
{
  put(1+get(i),i);
  count++;
}

init1
{
  limit=(count*ctl(0)/100);
  sum=0;
  for(ii=0;ii<256;ii++) { sum+=get(ii); if(sum>=limit) break; }
  rlo=ii;
  sum=0;
  for(ii=255;ii>0;ii--) { sum+=get(ii); if(sum>=limit) break; }
  rhi=ii;
}
 

R=scl(r,rlo,rhi,0,255);
G=scl(g,rlo,rhi,0,255);
B=scl(b,rlo,rhi,0,255);

****************************************************************
** SIMPLE GAMMA CORRECTION
****************************************************************
*  Slider 0: gamma (times 100), applies to all three channels
****************************************************************

init { calcGamma(ctl(0),0,256); }

R=get(r);
G=get(g);
B=get(b);
 

****************************************************************
** HORIZONTAL BLUR
****************************************************************
*  Slider 0: blurring size (is scaled to value between 1 and 15)
****************************************************************

init { sx=X/10; }

R=G=B=0;
ct=0;
for(ii=0;ii<val(0,1,15);ii++)
{
  R+=dr(ii,0);
  G+=dg(ii,0);
  B+=db(ii,0);

  R+=dr(-ii,0);
  G+=dg(-ii,0);
  B+=db(-ii,0);

  ct+=2;
}
R/=ct;
G/=ct;
B/=ct;

****************************************************************
** EMBOSS WITH BACKGROUND
****************************************************************
*  Slider 0: embossing strength (default value: 20)
****************************************************************

R=bgr+(r-dr(-1,-1))*ctl(0)/10;
G=bgg+(g-dg(-1,-1))*ctl(0)/10;
B=bgb+(b-db(-1,-1))*ctl(0)/10;
 

****************************************************************
** SHARPEN IMAGE
****************************************************************
*  Slider 0: sharpening strength (default 20)
****************************************************************

R=r+(r-cnv_r(1,1,1,1,0,1,1,1,1,8))*ctl(0)/20;
G=g+(g-cnv_g(1,1,1,1,0,1,1,1,1,8))*ctl(0)/20;
B=b+(b-cnv_b(1,1,1,1,0,1,1,1,1,8))*ctl(0)/20;
 

****************************************************************
** DOTTED IMAGE
****************************************************************
*  Slider 0: size of bounding dot rectangle (in pixels)
*         1: size of dot within rectangle (255.. full)
****************************************************************

dsize=ctl(0);
xrad=c2m(x%dsize-dsize/2,y%dsize-dsize/2);
if(xrad<=val(1,1,128)*dsize/256)
{
  centx=x-x%dsize+dsize/2;
  centy=y-y%dsize+dsize/2;
  R=src(centx,centy,0);
  G=src(centx,centy,1);
  B=src(centx,centy,2);
}
else R=G=B=0;
A=a;

****************************************************************
** HONEYCOMB
****************************************************************
*  Slider 0: element size (1/4th diameter of hexagon)
****************************************************************

s=ctl(0);  // scale
xx=x%(6*s);
yy=y%(4*s);

if(yy<2*s) 
{
  if(xx<3*s)
  {
    if((xx*xx+yy*yy)<((xx-3*s)*(xx-3*s)+(yy-2*s)*(yy-2*s)))
      { xp=0; yp=0; }
    else 
      { xp=3; yp=2; }
  }
  else  // xx>=3
  {
    if(((6*s-xx)*(6*s-xx)+yy*yy)<((xx-3*s)*(xx-3*s)+(yy-2*s)*(yy-2*s)))
      { xp=6; yp=0; }
    else 
      { xp=3; yp=2; }
  }
}
else // yy>=2
{
  if(xx<3*s)
  {
    if((xx*xx+(4*s-yy)*(4*s-yy))<((xx-3*s)*(xx-3*s)+(yy-2*s)*(yy-2*s)))
      { xp=0; yp=4; }
    else 
      { xp=3; yp=2; }
  }
  else  // xx>3
  {
    if(((6*s-xx)*(6*s-xx)+(4*s-yy)*(4*s-yy))<((xx-3*s)*(xx-3*s)+(yy-2*s)*(yy-2*s)))
      { xp=6; yp=4; }
    else 
      { xp=3; yp=2; }
  }
}

xx=(x-xx+xp*s);
yy=(y-yy+yp*s);

R=src(xx,yy,0);
G=src(xx,yy,1);
B=src(xx,yy,2);
 
 

****************************************************************
** ELLIPSE
****************************************************************
*  no sliders used
*
*  works only on layers (not on background!)
****************************************************************

rd=c2m(scl(x,0,X,-1024,1024),
       scl(y,0,Y,-1024,1024));
if(rd>=1024) A=0;
 

****************************************************************
** BUTTONIZE
****************************************************************
*  Slider 0: width/height of button
*         1: direction of light source
*         2: effect strength 
****************************************************************

bdistx=min(x,X-x); // distance from border, x
bdisty=min(y,Y-y);

if(bdistx<ctl(0) || bdisty<ctl(0))
{
  if(bdistx<bdisty) // left or right border
  {
    if(x<X/2)
      addv=scl(sin(val(1,0,1024)+0),-512,512,-ctl(2),ctl(2));
    else
      addv=scl(sin(val(1,0,1024)+512),-512,512,-ctl(2),ctl(2));
  }
  else     // upper or lower border
  {
    if(y<Y/2)  // upper
      addv=scl(sin(val(1,0,1024)+256),-512,512,-ctl(2),ctl(2));
    else
      addv=scl(sin(val(1,0,1024)+768),-512,512,-ctl(2),ctl(2));
  }

  // add factor for lightness
  R=r+addv;
  G=g+addv;
  B=b+addv;
}

****************************************************************
** TRIANGLES
****************************************************************
*  Slider 0: size of boxes 
*         1: effect strength
****************************************************************

xx=x%ctl(0);
yy=y%ctl(0);

if(xx<yy) 

  R+=ctl(1);
  G+=ctl(1);
  B+=ctl(1);
}
else if(xx>yy)

  R-=ctl(1);
  G-=ctl(1);
  B-=ctl(1);
}
 

****************************************************************
** CREATE SEAMLESS PATTERN
****************************************************************
*  no sliders used
****************************************************************

for(ii=0;ii<4;ii++) 
{
  xrel=scl(x,0,X,0,1024);
  yrel=scl(y,0,Y,0,1024);
  vx=(src(x,y,ii)    *      xrel *      yrel +    
      src(X-x,y,ii)  *(1024-xrel)*      yrel +
      src(x,Y-y,ii)  *      xrel *(1024-yrel)+
      src(X-X,Y-y,ii)*(1024-xrel)*(1024-yrel))/1024;
  setCHV(ii,vval);
}
 

****************************************************************
** SIMPLE (HARD) SHADOW W/BACKGROUND COLOR
****************************************************************
*  no sliders used
*
*  creates a shadow below all non-transparent objects
*  works only on layers (not on background!)
****************************************************************

init { 
  xx=ctl(0)*sin(val(1,0,1024))/512; 
  yy=ctl(0)*cos(val(1,0,1024))/512; 
}

// main pass

if(a==0 && (aa=da(xx,yy))>0)
{
  R=bgr; G=bgg; B=bgb;
  A=(aa*ctl(2))/255;
}
 

****************************************************************
** EXTENDED MEDIAN CUT 
****************************************************************
*  Slider 0: specifies which pixel of the neighbourhood to take
*            (0..darkest  4..classical median cut  8..lightest)
*
*  works slower than the built-in median cut algorithm, but
*  has more possibilities and demonstrates the use of the
*  sort()-function
****************************************************************

ct=0;
for(ix=-1;ix<=1;ix++)
  for(iy=-1;iy<=1;iy++)
  {
    put(dr(ix,iy),ct);
    put(dg(ix,iy),ct+10);
    put(db(ix,iy),ct+20);
    ct++;
  }
sort(0,9);
sort(10,9);
sort(20,9);

R=get(ctl(0));
G=get(10+ctl(0));
B=get(20+ctl(0));

****************************************************************
** RAINBOW FILTER
****************************************************************
*  Slider 0: X coordinate of center (picture relative)
*         1: Y coordinate of center
*         2: X width of ellipse
*         3: Y width of ellipse
*         4: bow width (in X direction)
*         5: transparency
****************************************************************

xm=val(0,0,1024);
ym=val(1,0,1024);
xw=val(2,0,1024);
yw=val(3,0,1024);
bw=val(4,0,1024);
xx=scl(x,0,X,0,1024);
yy=scl(y,0,Y,0,1024);
trans=val(5,0,255);

wid=xw-c2m(xx-xm,((yy-ym)*xw)/yw); // skaliere Bogen
if(wid>0 && wid<=bw)
{
  setHLS(scl(wid,0,bw,-100,900),128,255);
  R=(R*(255-trans)+r*trans)/255;
  G=(G*(255-trans)+g*trans)/255;
  B=(B*(255-trans)+b*trans)/255;
  A=255-trans;
}
 

****************************************************************
** EQUALIZE COLORS
****************************************************************
*  no sliders used
****************************************************************

init { sr=sg=sb=count=0; }

pass1 {
  light=(r+g+b)/3;
  rr=(r*256)/light;  
  rg=(g*256)/light;  
  rb=(b*256)/light;  
  sr+=rr;
  sg+=rg;
  sb+=rb;  
  count++;
}

init1 { 
  sr/=count;
  sg/=count;
  sb/=count;
}

// main pass

R=r*256/sr;
G=g*256/sg;
B=b*256/sb;