%ffp Category: "easy.Filter" Title: "GaussN" Version: "1.1" Filename: "gaussn.8bf" Author: "Alois Zingl" Copyright:"© 2010" URL: "http://free.pages.at/easyfilter/gauss.html" Description:"Arbitrary degree of the extended binomial Gaussian blur filter algorithm." ctl(0): "Radius (pixels)", divisor = (i0=5), range = (0,255*i0) ctl(1): "Approximation degree", range = (1, 8), page = 2 ctl(2): StaticText, "n = 1, r = 1, Radius = 0.00", size = (100,*) OnFilterStart: { // set padding to blur radius int radius = doingProxy?(ctl(0)+zoomFactor/2)/zoomFactor:ctl(0); needPadding = ctl(1)*radius*sqrt(3.0/ctl(1))/i0+3; // degree factor bandWidth = 100+4*needPadding; isTileable = !doingProxy; // split large images allocArray(0, ctl(1), 0, 0, 8); // double array for blur derivatives return false; } OnCtl(n): { // the get/put pixel buffer has only N_CELLS entries, so limit slider values int f = N_CELLS*i0*sqrt(ctl(1)/12.0)-i0; // degree factor if (e == FME_VALUECHANGED && n < 2 && ctl(0)*ctl(1) > f) setCtlVal(1-n, f/ctl(n)); // limit needed pixel buffer to N_CELLS return false; } ForEveryTile: { int radius = (ctl(0)+scaleFactor/2)/scaleFactor; // Blur radius int x, y, z, p, i, degree = ctl(1); radius = sqrt(12.0*radius*radius/degree/i0/i0+1); // degree factor setCtlTextv(2,"n = %d, r = %d, Radius = %.2f", // view degree, discrete & effective radius ctl(1), radius, sqrt(ctl(1)*(radius*radius-1)/12.0)*scaleFactor); for (z=0; z < Z; ++z) // for all color planes { // Update progress bar and cancel if ESC key was pressed if (updateProgress(y_start+(y_end-y_start)*z/Z, Y)) abort(); for (x = x_start; x < x_end; ++x) // vertical Blur... { double dif = 0, sum; ffillArray(0, 0.0); // set derivatives to 0 for (y = y_start-degree*radius; y < y_end; ++y) { // inner vertical Blur loop put(src(x, y+degree*(radius-1)/2, z), y); // buffer pixel, max buffer size: radius*degree for (p = 1, i = 0; i <= degree; ++i) // accumulate differences { if (y+(degree-i)*radius < y_start) break; // still in init stage, break dif += p*get(y-i*radius); // pixel p = p*(i-degree)/(i+1); // next binomial } for (sum = dif/radius, p = degree-1; p--; ) // accumulate pixel Blur fputArray(0, p, 0, 0, sum = fgetArray(0, p, 0, 0)+sum/radius); // slow in FM if (y >= y_start) pset(x, y, z, (int)sum); // set Blurred pixel } // y } // x for (y = y_start; y < y_end; ++y) // horizontal Blur... { double dif = 0, sum; ffillArray(0, 0.0); // set derivatives to 0 for (x = x_start-degree*radius; x < x_end; ++x) { // inner horizontal Blur loop put(pget(x+degree*(radius-1)/2, y, z), x); // buffer pixel for (p = 1, i = 0; i <= degree; ++i) // accumulate differences { if (x+(degree-i)*radius < x_start) break; // still in init stage, break dif += p*get(x-i*radius); // pixel p = p*(i-degree)/(i+1); // next binomial } for (sum = dif/radius, p = degree-1; p--; ) // accumulate pixel Blur fputArray(0, p, 0, 0, sum = fgetArray(0, p, 0, 0)+sum/radius); // slow in FM if (x >= x_start) pset(x, y, z, (int)sum); // set Blurred pixel } // x } // y } // color plane return true; //Done! } OnFilterEnd: { updateProgress(0, 1); freeArray(0); return false; }