shithub: brokentoys

Download patch

ref: e95e3c07981eab6b39a04df5446c998194acb6a2
parent: 317cb407d207055980e3b700e5dc5a5178b0672b
author: rodri <rgl@antares-labs.eu>
date: Sun Apr 27 13:11:16 EDT 2025

image: improve convolution tool. add some example filters

--- /dev/null
+++ b/image/blur.box16.mat
@@ -1,0 +1,4 @@
+0.0625 0.0625 0.0625 0.0625
+0.0625 0.0625 0.0625 0.0625
+0.0625 0.0625 0.0625 0.0625
+0.0625 0.0625 0.0625 0.0625
--- /dev/null
+++ b/image/blur.box25.mat
@@ -1,0 +1,5 @@
+0.04 0.04 0.04 0.04 0.04
+0.04 0.04 0.04 0.04 0.04
+0.04 0.04 0.04 0.04 0.04
+0.04 0.04 0.04 0.04 0.04
+0.04 0.04 0.04 0.04 0.04
--- /dev/null
+++ b/image/blur.box9.mat
@@ -1,0 +1,3 @@
+0.11111 0.11111 0.11111
+0.11111 0.11111 0.11111
+0.11111 0.11111 0.11111
--- a/image/convolution.c
+++ b/image/convolution.c
@@ -9,6 +9,7 @@
 #define clamp(a,b,c)	min(max(a,b),c)
 
 static int dim;
+static int saturate;
 
 static void
 fprintm(int fd, double *m, int dim)
@@ -20,6 +21,16 @@
 		fprint(fd, "%g%c", m[j*dim+i], i == dim-1? '\n': '\t');
 }
 
+static char *
+getline(Biobuf *b)
+{
+	char *line;
+
+	if((line = Brdline(b, '\n')) != nil)
+		line[Blinelen(b)-1] = 0;
+	return line;
+}
+
 static double *
 readkernel(int fd)
 {
@@ -32,7 +43,7 @@
 	if(bin == nil)
 		sysfatal("Bfdopen: %r");
 	do{
-		line = Brdline(bin, '\n');
+		line = getline(bin);
 		if(line == nil)
 			sysfatal("Brdline: %r");
 		dim = tokenize(line, f, nelem(f));
@@ -44,7 +55,7 @@
 		kern[j*dim+i] = strtod(f[i], nil);
 	j++;
 
-	while((line = Brdline(bin, '\n')) != nil){
+	while((line = getline(bin)) != nil){
 		if((nf = tokenize(line, f, nelem(f))) < 1)
 			continue;
 		if(nf != dim)
@@ -151,7 +162,9 @@
 		for(cp.y = imr.min.y; cp.y < imr.max.y; cp.y++)
 		for(cp.x = imr.min.x; cp.x < imr.max.x; cp.x++){
 			for(i = 0; i < d->nchan; i++){
-				im[i][cp.y*dim + cp.x] = sample(s, addpt(p, subpt(cp, imc)), i);
+				im[i][cp.y*dim + cp.x] = saturate
+				? clamp(sample(s, addpt(p, subpt(cp, imc)), i), 0, 0xFF)
+				: sample(s, addpt(p, subpt(cp, imc)), i);
 			}
 		}
 		for(i = 0; i < d->nchan; i++)
@@ -167,7 +180,7 @@
 static void
 usage(void)
 {
-	fprint(2, "usage: %s imgfile\n", argv0);
+	fprint(2, "usage: %s kernfile\n", argv0);
 	exits("usage");
 }
 
@@ -179,23 +192,24 @@
 	int fd;
 
 	ARGBEGIN{
+	case 's': saturate++; break;
 	default: usage();
 	}ARGEND;
 	if(argc != 1)
 		usage();
 
-	kern = readkernel(0);
+	fd = open(argv[0], OREAD);
+	if(fd < 0)
+		sysfatal("open: %r");
+	kern = readkernel(fd);
+	close(fd);
 	ckern = reverse(kern, dim);
 	free(kern);
 	kern = ckern;
 
-	fd = open(argv[0], OREAD);
-	if(fd < 0)
-		sysfatal("open: %r");
-	in = readmemimage(fd);
+	in = readmemimage(0);
 	if(in == nil)
 		sysfatal("readmemimage: %r");
-	close(fd);
 
 	out = allocmemimage(in->r, in->chan);
 	if(out == nil)
--- /dev/null
+++ b/image/edge.4.mat
@@ -1,0 +1,3 @@
+0 -1 0
+-1 4 -1
+0 -1 0
--- /dev/null
+++ b/image/edge.5.mat
@@ -1,0 +1,3 @@
+0 -1 0
+-1 5 -1
+0 -1 0
--- /dev/null
+++ b/image/sobel.Gx.mat
@@ -1,0 +1,3 @@
+-1 0 1
+-2 0 2
+-1 0 1
--- /dev/null
+++ b/image/sobel.Gy.mat
@@ -1,0 +1,3 @@
+-1 -2 -1
+0 0 0
+1 2 1
--