aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2020-06-08 20:19:38 +0000
committerrodri <rgl@antares-labs.eu>2020-06-08 20:19:38 +0000
commita5d30a2794ddba047e4dad0eda129d704322aead (patch)
treef3ec81f4251f0f791565aad4b851cfde9d0ee3c5
parent7df9940505915a1e57fd4daba9602e6466626c50 (diff)
downloadetoys-a5d30a2794ddba047e4dad0eda129d704322aead.tar.gz
etoys-a5d30a2794ddba047e4dad0eda129d704322aead.tar.bz2
etoys-a5d30a2794ddba047e4dad0eda129d704322aead.zip
new toy: imagelerp
-rw-r--r--imagelerp.c99
-rw-r--r--mkfile1
2 files changed, 100 insertions, 0 deletions
diff --git a/imagelerp.c b/imagelerp.c
new file mode 100644
index 0000000..c23bdad
--- /dev/null
+++ b/imagelerp.c
@@ -0,0 +1,99 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <memdraw.h>
+
+double
+flerp(double a, double b, double t)
+{
+ return a + (b - a)*t;
+}
+
+double
+fclamp(double n, double min, double max)
+{
+ return n < min? min: n > max? max: n;
+}
+
+Memimage*
+lerpimages(Memimage *i0, Memimage *i1, double blendf)
+{
+ Memimage *ri;
+ Point p;
+ uchar *s0, *s1, *d;
+ int bpp;
+
+ assert(i0->chan == i1->chan);
+ assert(Dx(i0->r) == Dx(i1->r) && Dy(i0->r) == Dy(i1->r));
+
+ ri = allocmemimage(i0->r, i0->chan);
+ if(ri == nil)
+ sysfatal("allocmemimage: %r");
+ bpp = (i0->depth+7)/8;
+
+ for(p.y = 0; p.y < i0->r.max.y; p.y++)
+ for(p.x = 0; p.x < i0->r.max.x; p.x++){
+ s0 = byteaddr(i0, addpt(i0->r.min, p));
+ s1 = byteaddr(i1, addpt(i1->r.min, p));
+ d = byteaddr(ri, addpt(ri->r.min, p));
+ switch(bpp){
+ case 4:
+ d[3] = flerp(s0[3], s1[3], blendf);
+ case 3:
+ d[2] = flerp(s0[2], s1[2], blendf);
+ case 2:
+ d[1] = flerp(s0[1], s1[1], blendf);
+ case 1:
+ d[0] = flerp(s0[0], s1[0], blendf);
+ }
+ }
+ return ri;
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s [-f factor] image0 image1\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ Memimage *m[2], *r;
+ char *s;
+ int fd;
+ double f;
+
+ f = 0.5;
+ ARGBEGIN{
+ case 'f':
+ f = strtod(EARGF(usage()), &s);
+ if(*s != 0)
+ sysfatal("wrong blending factor");
+ break;
+ default: usage();
+ }ARGEND;
+ if(argc != 2)
+ usage();
+
+ if(memimageinit() != 0)
+ sysfatal("memimageinit: %r");
+ fd = open(argv[0], OREAD);
+ if(fd < 0)
+ sysfatal("open: %r");
+ if((m[0] = readmemimage(fd)) == nil)
+ sysfatal("readmemimage: %r");
+ close(fd);
+ fd = open(argv[1], OREAD);
+ if(fd < 0)
+ sysfatal("open: %r");
+ if((m[1] = readmemimage(fd)) == nil)
+ sysfatal("readmemimage: %r");
+ close(fd);
+ r = lerpimages(m[0], m[1], fclamp(f, 0, 1));
+ if(writememimage(1, r) < 0)
+ sysfatal("writememimage: %r");
+ exits(nil);
+}
+
diff --git a/mkfile b/mkfile
index 8c07918..2848dce 100644
--- a/mkfile
+++ b/mkfile
@@ -9,6 +9,7 @@ TARG=\
isometric\
ptinline\
chain\
+ imagelerp\
HFILES=\
libgeometry/geometry.h\