%ffp Category: "AstroPlugins" Title: "Low End Smoother" Copyright: "Copyright ©2005 Author: "James Ryan" Organization: "Astroplugins" Filename: "Low End Smoother" Description: "" Version: "v1.0" URL: "www.grekalova.com" About: "AstroPlugins !V\n" "!c\n!A\n!U" Dialog: Text = "Astroplugins Low End Smoother !V !c !A" ctl(0):"&Radius * 10", val=1,range=(1,50) ctl(2):"Lower Limit", val=0 ctl(3):"Upper Limit", val=50 ForEveryTile: { double radius = ctl(0)/10.0; double sigma, sigma2; double l; int n; int length; int i, j, high, low, high1, low1, val; const bool PLOT = 0; const bool PRINT = 0; const bool DEBUG = 0; const bool USE_CNV = 0; radius = radius * 2.0 + 1.0; //scale approx same as Photoshop radius = fabs(radius) + 1.0; if (radius < 2.0) { if (Warn("Sub-pixel radii yield spurious results.") != IDOK) { abort(); } } sigma = sqrt(-(radius*radius)/(2.0*log(1.0/255.0))); sigma2 = 2.0 * sigma * sigma; ; l = sqrt(-sigma2 * log(1.0/255.0)); n = ceil(l) * 2; //round n up to an odd value. n |= 1; if (n > 256) { //exceeds number of put() cells... Error("Specified radius would require too many cells (%d).", n); abort(); } length = n / 2; //generate the bell-shaped Gaussian distribution curve... //curve[0] = 255; put(255, length); for (i = 1; i <= length; i++) { int temp = exp(-(i*i)/sigma2) * 255.0; //curve[-i] = curve[i] = temp; put(temp, length - i); put(temp, length + i); } if (PRINT) { // Print the curve. for (i = -length; i <= length; i++) { if (YesNo("curve[%d] = %d\n\nContinue?", i, get(length + i)) == IDNO) break; } } if (PLOT) { // Plot the Gaussian bell-shaped curve over a darkened // image background. // This updates fast, so set real-time tracking ON. setCtlProperties(0, CTP_TRACK); // Copy over a darkened version of the input image, // setting the alpha channel (if present) to fully opaque. for (y = y_start; y < y_end; y++) { if (updateProgress(y-y_start,y_end-y_start)) abort(); for (x = x_start; x < x_end; x++) { for (z = 0; z < Z; z++) { pset(x, y, z, z==3?255:src(x,y,z)/3); } } } // Draw the Y-axis. for (y = y_start; y < y_end; y++) { pset(X/2, y, 2, 255);//blue } // Draw the X-axis. for (x = x_start; x < x_end; x++) { pset(x, Y/2, 0, 255);//red } // Plot the Gaussian curve. for (i = -length; i <= length; i++) { pset(X/2 + i*10, Y/2 - get(length + i)*Y/512, 1, 255); //green } } else { // Apply Gaussian blur in the vertical and horizontal // directions. int sum, total; int xWork = x_end - x_start; int yWork = y_end - y_start; int totalWork = xWork + yWork; // This updates slowly, so set real-time tracking OFF. clearCtlProperties(0, CTP_TRACK); // Compute total weight total = 0; for (i = -length; i <= length; i++) { total += get(length + i); } if (DEBUG) Info("total = %d", total); // Apply vertical Gaussian blur... for (x = x_start; x < x_end; x++) { if (updateProgress(x-x_start, totalWork)) abort(); for (y = y_start; y < y_end; y++) { for (z = 0; z < Z; z++) { { sum = 0; for (i = -length; i <= length; ++i) { sum += src(x, y+i, z)*get(length + i); val = sum/total; high = val>>8; low = val<<24; low = low>>24; val = high<<8; val = val + low; tset(x,y,z,high); t2set(x,y,z,low); } } } } } // Apply horizontal Gaussian blur... for (y = y_start; y < y_end; y++) { if (updateProgress(y-y_start+xWork, totalWork)) abort(); for (x = x_start; x < x_end; x++) { for (z = 0; z < Z; z++) { { sum = 0; for (i = -length; i <= length; ++i) { high = tget(x+i, y, z)<<8; low = t2get(x+i, y, z); val = high + low; sum += val*get(length + i); } if (src(x,y,z) > ctl(2) && src(x,y,z) < ctl(3)) { pset(x, y, z, sum/total); } else pset(x,y,z,src(x,y,z)); } } } } }//if // Reset the progress bar. updateProgress(0,100); return true; //Done! }//ForEveryTile