Created
August 2, 2012 15:04
-
-
Save zero-is-one/3237735 to your computer and use it in GitHub Desktop.
Superfastblur Algorithm for Openframeworks with alpha support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Super Fast Blur v1.1 | |
// by Mario Klingemann <http://incubator.quasimondo.com> | |
// converted to C++ by Mehmet Akten, <http://www.memo.tv> | |
// Add alpha support by Victor Sigma, <http://www.aphes.com> | |
// | |
// Tip: Multiple invovations of this filter with a small | |
// radius will approximate a gaussian blur quite well. | |
// | |
void superFastBlur(unsigned char *pix, int w, int h, int radius) { | |
if (radius<1) return; | |
int wm=w-1; | |
int hm=h-1; | |
int wh=w*h; | |
int div=radius+radius+1; | |
unsigned char *r=new unsigned char[wh]; | |
unsigned char *g=new unsigned char[wh]; | |
unsigned char *b=new unsigned char[wh]; | |
unsigned char *a=new unsigned char[wh]; | |
int rsum,gsum,bsum,asum,x,y,i,p,p1,p2,yp,yi,yw; | |
int *vMIN = new int[MAX(w,h)]; | |
int *vMAX = new int[MAX(w,h)]; | |
unsigned char *dv=new unsigned char[256*div]; | |
for (i=0;i<256*div;i++) dv[i]=(i/div); | |
yw=yi=0; | |
for (y=0;y<h;y++){ | |
rsum=gsum=bsum=asum=0; | |
for(i=-radius;i<=radius;i++){ | |
p = (yi + MIN(wm, MAX(i,0))) * 4; | |
rsum += pix[p]; | |
gsum += pix[p+1]; | |
bsum += pix[p+2]; | |
asum += pix[p+3]; | |
} | |
for (x=0;x<w;x++){ | |
r[yi]=dv[rsum]; | |
g[yi]=dv[gsum]; | |
b[yi]=dv[bsum]; | |
a[yi]=dv[asum]; | |
if(y==0){ | |
vMIN[x]=MIN(x+radius+1,wm); | |
vMAX[x]=MAX(x-radius,0); | |
} | |
p1 = (yw+vMIN[x])*4; | |
p2 = (yw+vMAX[x])*4; | |
rsum += pix[p1] - pix[p2]; | |
gsum += pix[p1+1] - pix[p2+1]; | |
bsum += pix[p1+2] - pix[p2+2]; | |
asum += pix[p1+3] - pix[p2+3]; | |
yi++; | |
} | |
yw+=w; | |
} | |
for (x=0;x<w;x++){ | |
rsum=gsum=bsum=asum=0; | |
yp=-radius*w; | |
for(i=-radius;i<=radius;i++){ | |
yi=MAX(0,yp)+x; | |
rsum+=r[yi]; | |
gsum+=g[yi]; | |
bsum+=b[yi]; | |
asum+=a[yi]; | |
yp+=w; | |
} | |
yi=x; | |
for (y=0;y<h;y++){ | |
pix[yi*4] = dv[rsum]; | |
pix[yi*4 + 1] = dv[gsum]; | |
pix[yi*4 + 2] = dv[bsum]; | |
pix[yi*4 + 3] = dv[asum]; | |
if(x==0){ | |
vMIN[y]=MIN(y+radius+1,hm)*w; | |
vMAX[y]=MAX(y-radius,0)*w; | |
} | |
p1=x+vMIN[y]; | |
p2=x+vMAX[y]; | |
rsum+=r[p1]-r[p2]; | |
gsum+=g[p1]-g[p2]; | |
bsum+=b[p1]-b[p2]; | |
asum+=a[p1]-a[p2]; | |
yi+=w; | |
} | |
} | |
delete r; | |
delete g; | |
delete b; | |
delete a; | |
delete vMIN; | |
delete vMAX; | |
delete dv; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment