ref: 558bc6b21da1130b09dfb09d216736f88016c1c6
dir: /ifilter.c/
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#define MIN(x,y) ((x)<(y)?(x):(y))
typedef void(*filterfun)(uchar[3]);
void
grayscale(uchar p[3])
{
uchar v = 0.2126*p[0] + 0.7152*p[1] + 0.0722*p[2];
p[0] = p[1] = p[2] = v;
}
void
sepia(uchar p[3])
{
float r, g, b;
r = 0.393*p[2] + 0.769*p[1] + 0.189*p[0];
g = 0.349*p[2] + 0.686*p[1] + 0.168*p[0];
b = 0.272*p[2] + 0.534*p[1] + 0.131*p[0];
p[2] = MIN(r, 255);
p[1] = MIN(g, 255);
p[0] = MIN(b, 255);
}
void
usage(void)
{
fprint(2, "usage: %s [grayscale|sepia]\n", argv0);
exits("usage");
}
void
main(int argc, char *argv[])
{
Memimage *i;
int w, h, p, n;
uchar *buf;
filterfun filter;
filter = nil;
ARGBEGIN{
}ARGEND;
if(argc!=1)
usage();
if(strcmp(*argv, "grayscale")==0)
filter = grayscale;
else if(strcmp(*argv, "sepia")==0)
filter = sepia;
else
usage();
if(memimageinit()<0)
sysfatal("memimageinit: %r");
i = readmemimage(0);
if(i==nil)
sysfatal("readmemimage: %r");
w = Dx(i->r);
h = Dy(i->r);
n = 4*w*h*sizeof(uchar);
buf = malloc(n);
if(buf==nil)
sysfatal("malloc: %r");
if(unloadmemimage(i, i->r, buf, n)<0)
sysfatal("unloadmemimage: %r");
for(p = 0; p < n; p+=4){
filter(buf+p);
}
if(loadmemimage(i, i->r, buf, n)<0)
sysfatal("unloadmemimage: %r");
writememimage(1, i);
freememimage(i);
exits(nil);
}