ref: 844c071da04aee8af6b52c23184ce8c533a36c19
parent: 4e545a974d714250dd3d693bccabf612a7c18029
author: phil9 <telephil9@gmail.com>
date: Sun Nov 28 16:48:00 EST 2021
add gaussian blur
--- a/blur.c
+++ b/blur.c
@@ -81,6 +81,63 @@
return out;
}
+uchar*
+gaussian(uchar *data, int w, int h, int depth)
+{
+ const double E = 2.7182818284590452354;
+ const double Π = 3.14159265358979323846;
+ uchar *out;
+ int kw, x, y, kx, ky;
+ double *k, σ, s, e, n, d, v, r, g, b;
+
+ if(size < 0)
+ sysfatal("gaussian filter needs a size argument");
+ out = malloc(depth*w*h*sizeof(uchar));
+ if(out == nil)
+ return nil;
+ σ = (double)size / 2.0;
+ kw = 2 * size + 1;
+ k = malloc(kw*kw*sizeof(double));
+ if(k == nil)
+ return nil;
+ s = 0.0f;
+ for(y = -size; y <= size; y++){
+ for(x = -size; x <= size; x++){
+ n = (double)(-(x * x + y * y));
+ d = 2 * σ * σ;
+ e = pow(E, n / d);
+ v = e / (2 * Π * σ * σ);
+ k[(x + size) + kw * (y + size)] = v;
+ s += v;
+ }
+ }
+ for(y = 0; y < kw; y++){
+ for(x = 0; x < kw; x++){
+ k[x + kw * y] /= s;
+ }
+ }
+ for(y = size; y < (h - size); y++){
+ for(x = size; x < (w - size); x++){
+ r = g = b = 0.0;
+ for(ky = -size; ky <= size; ky++){
+ for(kx = -size; kx <= size; kx++){
+ v = k[(kx + size) + kw * (ky + size)];
+#define P(X,Y,C) data[((X) + (w*(Y)))*depth + C]
+ r += (double)P(x - kx, y - ky, 0) * v;
+ g += (double)P(x - kx, y - ky, 1) * v;
+ b += (double)P(x - kx, y - ky, 2) * v;
+#undef P
+ }
+ }
+ out[(x + w*y)*depth + 0] = r;
+ out[(x + w*y)*depth + 1] = g;
+ out[(x + w*y)*depth + 2] = b;
+ }
+ }
+ free(k);
+ return out;
+}
+
void
usage(void)
{
@@ -91,6 +148,7 @@
static Filter filters[] = {
{ "box", box },
{ "pixelate", pixelate },
+ { "gaussian", gaussian },
};
void