shithub: ifilter

Download patch

ref: 67107b61b644fa2fe1376ff34dd928b70e1fdda8
parent: 558bc6b21da1130b09dfb09d216736f88016c1c6
author: phil9 <[email protected]>
date: Sun Sep 5 01:35:18 EDT 2021

add color inversion filter

--- a/README
+++ b/README
@@ -8,6 +8,7 @@
 Available color filters are:
 - grayscale
 - sepia
+- invert
 
-usage: ifilter [grayscale|sepia]
+usage: ifilter [grayscale|sepia|invert]
 
--- a/ifilter.c
+++ b/ifilter.c
@@ -5,8 +5,14 @@
 
 #define MIN(x,y) ((x)<(y)?(x):(y))
 
-typedef void(*filterfun)(uchar[3]);
+typedef struct Filter Filter;
 
+struct Filter
+{
+	const char *name;
+	void (*filter)(uchar[3]);
+};
+
 void
 grayscale(uchar p[3])
 {
@@ -28,12 +34,26 @@
 }
 
 void
+invert(uchar p[3])
+{
+	p[0] = 255 - p[0];
+	p[1] = 255 - p[1];
+	p[2] = 255 - p[2];
+}
+
+void
 usage(void)
 {
-	fprint(2, "usage: %s [grayscale|sepia]\n", argv0);
+	fprint(2, "usage: %s [grayscale|sepia|invert]\n", argv0);
 	exits("usage");
 }
 
+static Filter filters[] = {
+	{ "grayscale", grayscale },
+	{ "sepia", sepia },
+	{ "invert", invert },
+};
+
 void
 main(int argc, char *argv[])
 {
@@ -40,18 +60,20 @@
 	Memimage *i;
 	int w, h, p, n;
 	uchar *buf;
-	filterfun filter;
+	Filter *f;
 
-	filter = nil;
+	f = nil;
 	ARGBEGIN{
 	}ARGEND;
 	if(argc!=1)
 		usage();
-	if(strcmp(*argv, "grayscale")==0)
-		filter = grayscale;
-	else if(strcmp(*argv, "sepia")==0)
-		filter = sepia;
-	else
+	for(n=0; n<nelem(filters); n++){
+		if(strcmp(*argv, filters[n].name)==0){
+			f = filters+n;
+			break;
+		}
+	}
+	if(f==nil)
 		usage();
 	if(memimageinit()<0)
 		sysfatal("memimageinit: %r");
@@ -66,9 +88,8 @@
 		sysfatal("malloc: %r");
 	if(unloadmemimage(i, i->r, buf, n)<0)
 		sysfatal("unloadmemimage: %r");
-	for(p = 0; p < n; p+=4){
-		filter(buf+p);
-	}
+	for(p = 0; p < n; p+=4)
+		f->filter(buf+p);
 	if(loadmemimage(i, i->r, buf, n)<0)
 		sysfatal("unloadmemimage: %r");
 	writememimage(1, i);