commit c216ac3049102422a41ba2c9476b0dbf4f3e4034
Author:     Mattias Andrée <[email protected]>
AuthorDate: Sun Jul 16 00:59:42 2017 +0200
Commit:     Mattias Andrée <[email protected]>
CommitDate: Sun Jul 16 00:59:42 2017 +0200

    Use #include instead of #define
    
    Signed-off-by: Mattias Andrée <[email protected]>

diff --git a/Makefile b/Makefile
index f2e460e..fb876e1 100644
--- a/Makefile
+++ b/Makefile
@@ -112,6 +112,7 @@ COMMON_OBJ =\
 HDR =\
        arg.h\
        common.h\
+       define-functions.h\
        stream.h\
        util.h\
        util/to.h\
diff --git a/src/blind-apply-palette.c b/src/blind-apply-palette.c
index 1e0d5f8..113f57b 100644
--- a/src/blind-apply-palette.c
+++ b/src/blind-apply-palette.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("palette-stream")
@@ -16,55 +17,8 @@ distance_xyz(double x1, double y1, double z1, double a1, 
double x2, double y2, d
        return sqrt(x2 + y2 + z2 + a2);
 }
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream, struct stream *palette, char 
*pal)\
-       {\
-               size_t i, j, n, m;\
-               size_t palsiz = palette->width * palette->height;\
-               size_t best = 0;\
-               TYPE x, y, z, a, lx = 0, ly = 0, lz = 0, la = 0;\
-               TYPE cx, cy, cz, ca;\
-               double distance, best_distance = 0;\
-               while (eread_frame(palette, pal)) {\
-                       m = stream->frame_size;\
-                       do {\
-                               n = MIN(stream->ptr, m) / stream->pixel_size;\
-                               for (i = 0; i < n; i++) {\
-                                       x = ((TYPE *)(stream->buf + i * 
stream->pixel_size))[0];\
-                                       y = ((TYPE *)(stream->buf + i * 
stream->pixel_size))[1];\
-                                       z = ((TYPE *)(stream->buf + i * 
stream->pixel_size))[2];\
-                                       a = ((TYPE *)(stream->buf + i * 
stream->pixel_size))[3];\
-                                       if ((!i && m == stream->frame_size) || 
x != lx || y != ly || z != lz || a != la) {\
-                                               for (j = 0; j < palsiz; j++) {\
-                                                       cx = ((TYPE *)(pal + j 
* stream->pixel_size))[0];\
-                                                       cy = ((TYPE *)(pal + j 
* stream->pixel_size))[1];\
-                                                       cz = ((TYPE *)(pal + j 
* stream->pixel_size))[2];\
-                                                       ca = ((TYPE *)(pal + j 
* stream->pixel_size))[3];\
-                                                       distance = 
compare((double)x, (double)y, (double)z, (double)a,\
-                                                                          
(double)cx, (double)cy, (double)cz, (double)ca);\
-                                                       if (!j || distance < 
best_distance) {\
-                                                               best_distance = 
distance;\
-                                                               best = j;\
-                                                       }\
-                                               }\
-                                               lx = x, ly = y, lz = z, la = a;\
-                                       }\
-                                       memcpy(stream->buf + i * 
stream->pixel_size,\
-                                              pal + best * stream->pixel_size,\
-                                              stream->pixel_size);\
-                               }\
-                               m -= n *= stream->pixel_size;\
-                               ewriteall(STDOUT_FILENO, stream->buf, n, 
"<stdout>");\
-                               memmove(stream->buf, stream->buf + n, 
stream->ptr -= n);\
-                       } while (m && eread_stream(stream, SIZE_MAX));\
-                       if (m)\
-                               eprintf("%s: incomplete frame\n", 
stream->file);\
-               }\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-apply-palette.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -101,3 +55,53 @@ main(int argc, char *argv[])
        free(pal);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream, struct stream *palette, char *pal)
+{
+       size_t i, j, n, m;
+       size_t palsiz = palette->width * palette->height;
+       size_t best = 0;
+       TYPE x, y, z, a, lx = 0, ly = 0, lz = 0, la = 0;
+       TYPE cx, cy, cz, ca;
+       double distance, best_distance = 0;
+       while (eread_frame(palette, pal)) {
+               m = stream->frame_size;
+               do {
+                       n = MIN(stream->ptr, m) / stream->pixel_size;
+                       for (i = 0; i < n; i++) {
+                               x = ((TYPE *)(stream->buf + i * 
stream->pixel_size))[0];
+                               y = ((TYPE *)(stream->buf + i * 
stream->pixel_size))[1];
+                               z = ((TYPE *)(stream->buf + i * 
stream->pixel_size))[2];
+                               a = ((TYPE *)(stream->buf + i * 
stream->pixel_size))[3];
+                               if ((!i && m == stream->frame_size) || x != lx 
|| y != ly || z != lz || a != la) {
+                                       for (j = 0; j < palsiz; j++) {
+                                               cx = ((TYPE *)(pal + j * 
stream->pixel_size))[0];
+                                               cy = ((TYPE *)(pal + j * 
stream->pixel_size))[1];
+                                               cz = ((TYPE *)(pal + j * 
stream->pixel_size))[2];
+                                               ca = ((TYPE *)(pal + j * 
stream->pixel_size))[3];
+                                               distance = compare((double)x, 
(double)y, (double)z, (double)a,
+                                                                  (double)cx, 
(double)cy, (double)cz, (double)ca);
+                                               if (!j || distance < 
best_distance) {
+                                                       best_distance = 
distance;
+                                                       best = j;
+                                               }
+                                       }
+                                       lx = x, ly = y, lz = z, la = a;
+                               }
+                               memcpy(stream->buf + i * stream->pixel_size,
+                                      pal + best * stream->pixel_size,
+                                      stream->pixel_size);
+                       }
+                       m -= n *= stream->pixel_size;
+                       ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");
+                       memmove(stream->buf, stream->buf + n, stream->ptr -= n);
+               } while (m && eread_stream(stream, SIZE_MAX));
+               if (m)
+                       eprintf("%s: incomplete frame\n", stream->file);
+       }
+}
+
+#endif
diff --git a/src/blind-chroma-key.c b/src/blind-chroma-key.c
index b9deadb..f670317 100644
--- a/src/blind-chroma-key.c
+++ b/src/blind-chroma-key.c
@@ -1,64 +1,11 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("key-stream")
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream, struct stream *key)\
-       {\
-               size_t i, n, m = 0;\
-               TYPE x1, y1, z1, a1, a2, variance2, *keyxyza;\
-               TYPE x, y, z, d;\
-               do {\
-                       if (!m) {\
-                               m = stream->frame_size;\
-                               while (key->ptr < key->frame_size)\
-                                       if (!eread_stream(key, key->frame_size 
- key->ptr))\
-                                               return;\
-                               keyxyza = (TYPE *)(key->buf);\
-                               x1 = keyxyza[0];\
-                               y1 = keyxyza[1];\
-                               z1 = keyxyza[2];\
-                               a1 = keyxyza[3];\
-                               x = x1 - keyxyza[4];\
-                               y = y1 - keyxyza[5];\
-                               z = z1 - keyxyza[6];\
-                               a2 = keyxyza[7];\
-                               variance2 = x * x + y * y + z * z;\
-                               /* TODO add more formulae: 
https://en.wikipedia.org/wiki/Color_difference */\
-                               if (a2 > a1) {\
-                                       a1 = 1 - a1;\
-                                       a2 = 1 - a2;\
-                               }\
-                               memmove(key->buf, key->buf + key->frame_size,\
-                                       key->ptr -= key->frame_size);\
-                       }\
-                       n = MIN(stream->ptr, m) / stream->pixel_size;\
-                       for (i = 0; i < n; i++) {\
-                               x = ((TYPE *)(stream->buf))[4 * i + 0] - x1;\
-                               y = ((TYPE *)(stream->buf))[4 * i + 1] - y1;\
-                               z = ((TYPE *)(stream->buf))[4 * i + 2] - z1;\
-                               d = x * x + y * y + z * z;\
-                               if (d <= variance2) {\
-                                       if (a1 == a2)\
-                                               d = 0;\
-                                       else\
-                                               d = sqrt(d / variance2) * (a1 - 
a2) + a2;\
-                                       ((TYPE *)(stream->buf))[4 * i + 3] *= 
d;\
-                               }\
-                       }\
-                       n *= stream->pixel_size;\
-                       m -= n;\
-                       ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");\
-                       memmove(stream->buf, stream->buf + n, stream->ptr -= 
n);\
-               } while (eread_stream(stream, SIZE_MAX));\
-               if (stream->ptr)\
-                       eprintf("%s: incomplete frame\n", stream->file);\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-chroma-key.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -89,3 +36,60 @@ main(int argc, char *argv[])
        process(&stream, &key);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream, struct stream *key)
+{
+       size_t i, n, m = 0;
+       TYPE x1, y1, z1, a1, a2, variance2, *keyxyza;
+       TYPE x, y, z, d;
+       do {
+               if (!m) {
+                       m = stream->frame_size;
+                       while (key->ptr < key->frame_size)
+                               if (!eread_stream(key, key->frame_size - 
key->ptr))
+                                       return;
+                       keyxyza = (TYPE *)(key->buf);
+                       x1 = keyxyza[0];
+                       y1 = keyxyza[1];
+                       z1 = keyxyza[2];
+                       a1 = keyxyza[3];
+                       x = x1 - keyxyza[4];
+                       y = y1 - keyxyza[5];
+                       z = z1 - keyxyza[6];
+                       a2 = keyxyza[7];
+                       variance2 = x * x + y * y + z * z;
+                       /* TODO add more formulae: 
https://en.wikipedia.org/wiki/Color_difference */
+                       if (a2 > a1) {
+                               a1 = 1 - a1;
+                               a2 = 1 - a2;
+                       }
+                       memmove(key->buf, key->buf + key->frame_size,
+                               key->ptr -= key->frame_size);
+               }
+               n = MIN(stream->ptr, m) / stream->pixel_size;
+               for (i = 0; i < n; i++) {
+                       x = ((TYPE *)(stream->buf))[4 * i + 0] - x1;
+                       y = ((TYPE *)(stream->buf))[4 * i + 1] - y1;
+                       z = ((TYPE *)(stream->buf))[4 * i + 2] - z1;
+                       d = x * x + y * y + z * z;
+                       if (d <= variance2) {
+                               if (a1 == a2)
+                                       d = 0;
+                               else
+                                       d = sqrt(d / variance2) * (a1 - a2) + 
a2;
+                               ((TYPE *)(stream->buf))[4 * i + 3] *= d;
+                       }
+               }
+               n *= stream->pixel_size;
+               m -= n;
+               ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");
+               memmove(stream->buf, stream->buf + n, stream->ptr -= n);
+       } while (eread_stream(stream, SIZE_MAX));
+       if (stream->ptr)
+               eprintf("%s: incomplete frame\n", stream->file);
+}
+
+#endif
diff --git a/src/blind-cone-gradient.c b/src/blind-cone-gradient.c
index fc23210..c42a7e7 100644
--- a/src/blind-cone-gradient.c
+++ b/src/blind-cone-gradient.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-a | -s] -w width -h height")
@@ -9,69 +10,8 @@ static size_t width = 0;
 static size_t height = 0;
 static int with_multiplier = 0;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream)\
-       {\
-               typedef TYPE pixel_t[4];\
-               pixel_t buf[BUFSIZ / sizeof(pixel_t)];\
-               TYPE *params, x1, y1, x2, y2;\
-               TYPE x, y, u, v, m = 1;\
-               size_t ix, iy, ptr = 0;\
-               for (;;) {\
-                       while (stream->ptr < stream->frame_size) {\
-                               if (!eread_stream(stream, stream->frame_size - 
stream->ptr)) {\
-                                       ewriteall(STDOUT_FILENO, buf, ptr * 
sizeof(*buf), "<stdout>");\
-                                       return;\
-                               }\
-                       }\
-                       params = (TYPE *)stream->buf;\
-                       x1 = (params)[0];\
-                       y1 = (params)[1];\
-                       x2 = (params)[4];\
-                       y2 = (params)[5];\
-                       if (with_multiplier)\
-                               m = (params)[9];\
-                       memmove(stream->buf, stream->buf + stream->frame_size,\
-                               stream->ptr -= stream->frame_size);\
-                       \
-                       x2 -= x1;\
-                       y2 -= y1;\
-                       u = atan2(y2, x2);\
-                       \
-                       for (iy = 0; iy < height; iy++) {\
-                               y = (TYPE)iy - y1;\
-                               for (ix = 0; ix < width; ix++) {\
-                                       x = (TYPE)ix - x1;\
-                                       if (!x && !y) {\
-                                               v = 0.5;\
-                                       } else {\
-                                               v = atan2(y, x);\
-                                               v -= u;\
-                                               v += 2 * (TYPE)M_PI;\
-                                               v = mod(v, 2 * (TYPE)M_PI);\
-                                               v /= 2 * (TYPE)M_PI;\
-                                               if (anticlockwise)\
-                                                       v = 1 - v;\
-                                               v *= m;\
-                                               if (symmetric) {\
-                                                       v = mod(2 * v, 
(TYPE)2);\
-                                                       if (v > 1)\
-                                                               v = 2 - v;\
-                                               }\
-                                       }\
-                                       buf[ptr][0] = buf[ptr][1] = buf[ptr][2] 
= buf[ptr][3] = v;\
-                                       if (++ptr == ELEMENTSOF(buf)) {\
-                                               ewriteall(STDOUT_FILENO, buf, 
sizeof(buf), "<stdout>");\
-                                               ptr = 0;\
-                                       }\
-                               }\
-                       }\
-               }\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-cone-gradient.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -81,13 +21,9 @@ main(int argc, char *argv[])
 
        ARGBEGIN {
        case 'a':
-               if (symmetric)
-                       usage();
                anticlockwise = 1;
                break;
        case 's':
-               if (anticlockwise)
-                       usage();
                symmetric = 1;
                break;
        case 'w':
@@ -100,7 +36,7 @@ main(int argc, char *argv[])
                usage();
        } ARGEND;
 
-       if (!width || !height || argc)
+       if (!width || !height || (symmetric && anticlockwise) || argc)
                usage();
 
        eopen_stream(&stream, NULL);
@@ -126,3 +62,68 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       typedef TYPE pixel_t[4];
+       pixel_t buf[BUFSIZ / sizeof(pixel_t)];
+       TYPE *params, x1, y1, x2, y2;
+       TYPE x, y, u, v, m = 1;
+       size_t ix, iy, ptr = 0;
+
+       for (;;) {
+               while (stream->ptr < stream->frame_size) {
+                       if (!eread_stream(stream, stream->frame_size - 
stream->ptr)) {
+                               ewriteall(STDOUT_FILENO, buf, ptr * 
sizeof(*buf), "<stdout>");
+                               return;
+                       }
+               }
+               params = (TYPE *)stream->buf;
+               x1 = (params)[0];
+               y1 = (params)[1];
+               x2 = (params)[4];
+               y2 = (params)[5];
+               if (with_multiplier)
+                       m = (params)[9];
+               memmove(stream->buf, stream->buf + stream->frame_size,
+                       stream->ptr -= stream->frame_size);
+
+               x2 -= x1;
+               y2 -= y1;
+               u = atan2(y2, x2);
+
+               for (iy = 0; iy < height; iy++) {
+                       y = (TYPE)iy - y1;
+                       for (ix = 0; ix < width; ix++) {
+                               x = (TYPE)ix - x1;
+                               if (!x && !y) {
+                                       v = 0.5;
+                               } else {
+                                       v = atan2(y, x);
+                                       v -= u;
+                                       v += 2 * (TYPE)M_PI;
+                                       v = mod(v, 2 * (TYPE)M_PI);
+                                       v /= 2 * (TYPE)M_PI;
+                                       if (anticlockwise)
+                                               v = 1 - v;
+                                       v *= m;
+                                       if (symmetric) {
+                                               v = mod(2 * v, (TYPE)2);
+                                               if (v > 1)
+                                                       v = 2 - v;
+                                       }
+                               }
+                               buf[ptr][0] = buf[ptr][1] = buf[ptr][2] = 
buf[ptr][3] = v;
+                               if (++ptr == ELEMENTSOF(buf)) {
+                                       ewriteall(STDOUT_FILENO, buf, 
sizeof(buf), "<stdout>");
+                                       ptr = 0;
+                               }
+                       }
+               }
+       }
+}
+
+#endif
diff --git a/src/blind-coordinate-field.c b/src/blind-coordinate-field.c
index 2d73399..884b513 100644
--- a/src/blind-coordinate-field.c
+++ b/src/blind-coordinate-field.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-f frames | -f 'inf'] [-F pixel-format] -w width -h height")
@@ -6,25 +7,8 @@ USAGE("[-f frames | -f 'inf'] [-F pixel-format] -w width -h 
height")
 static struct stream stream = { .width = 0, .height = 0, .frames = 1 };
 static int inf = 0;
 
-#define PROCESS(TYPE)\
-       do {\
-               TYPE buf[4] = {0, 0, 0, 0};\
-               size_t x, y;\
-               \
-               while (inf || stream.frames--) {\
-                       for (y = 0; y < stream.height; y++) {\
-                               buf[1] = (TYPE)y;\
-                               for (x = 0; x < stream.width; x++) {\
-                                       buf[0] = (TYPE)x;\
-                                       if (write(STDOUT_FILENO, buf, 
sizeof(buf)) < 0)\
-                                               eprintf("write <stdout>:");\
-                               }\
-                       }\
-               }\
-       } while (0)
-
-static void process_lf(void) {PROCESS(double);}
-static void process_f(void) {PROCESS(float);}
+#define FILE "blind-coordinate-field.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -75,3 +59,24 @@ main(int argc, char *argv[])
        process();
        return 0;
 }
+
+#else
+
+static void
+PROCESS(void)
+{
+       TYPE buf[4] = {0, 0, 0, 0};
+       size_t x, y;
+       while (inf || stream.frames--) {
+               for (y = 0; y < stream.height; y++) {
+                       buf[1] = (TYPE)y;
+                       for (x = 0; x < stream.width; x++) {
+                               buf[0] = (TYPE)x;
+                               if (write(STDOUT_FILENO, buf, sizeof(buf)) < 0)
+                                       eprintf("write <stdout>:");
+                       }
+               }
+       }
+}
+
+#endif
diff --git a/src/blind-cross-product.c b/src/blind-cross-product.c
index 5f79424..1c369ba 100644
--- a/src/blind-cross-product.c
+++ b/src/blind-cross-product.c
@@ -1,32 +1,11 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("right-hand-stream")
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *left, struct stream *right, size_t n)\
-       {\
-               size_t i;\
-               TYPE *lx, *ly, *lz, *la, *rx, *ry, *rz, *ra, x, y, z, a;\
-               for (i = 0; i < n; i += 4 * sizeof(TYPE)) {\
-                       lx = ((TYPE *)(left->buf + i)) + 0, rx = ((TYPE 
*)(right->buf + i)) + 0;\
-                       ly = ((TYPE *)(left->buf + i)) + 1, ry = ((TYPE 
*)(right->buf + i)) + 1;\
-                       lz = ((TYPE *)(left->buf + i)) + 2, rz = ((TYPE 
*)(right->buf + i)) + 2;\
-                       la = ((TYPE *)(left->buf + i)) + 3, ra = ((TYPE 
*)(right->buf + i)) + 3;\
-                       x = *ly * *rz - *lz * *ry;\
-                       y = *lz * *rx - *lx * *rz;\
-                       z = *lx * *ry - *ly * *rx;\
-                       a = *la * *ra;\
-                       *lx = x;\
-                       *ly = y;\
-                       *lz = z;\
-                       *la = a;\
-               }\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-cross-product.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -51,3 +30,28 @@ main(int argc, char *argv[])
        process_two_streams(&left, &right, STDOUT_FILENO, "<stdout>", process);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *left, struct stream *right, size_t n)
+{
+       size_t i;
+       TYPE *lx, *ly, *lz, *la, *rx, *ry, *rz, *ra, x, y, z, a;
+       for (i = 0; i < n; i += 4 * sizeof(TYPE)) {
+               lx = ((TYPE *)(left->buf + i)) + 0, rx = ((TYPE *)(right->buf + 
i)) + 0;
+               ly = ((TYPE *)(left->buf + i)) + 1, ry = ((TYPE *)(right->buf + 
i)) + 1;
+               lz = ((TYPE *)(left->buf + i)) + 2, rz = ((TYPE *)(right->buf + 
i)) + 2;
+               la = ((TYPE *)(left->buf + i)) + 3, ra = ((TYPE *)(right->buf + 
i)) + 3;
+               x = *ly * *rz - *lz * *ry;
+               y = *lz * *rx - *lx * *rz;
+               z = *lx * *ry - *ly * *rx;
+               a = *la * *ra;
+               *lx = x;
+               *ly = y;
+               *lz = z;
+               *la = a;
+       }
+}
+
+#endif
diff --git a/src/blind-dot-product.c b/src/blind-dot-product.c
index b9699c2..1d7053d 100644
--- a/src/blind-dot-product.c
+++ b/src/blind-dot-product.c
@@ -1,27 +1,11 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("right-hand-stream")
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *left, struct stream *right, size_t n)\
-       {\
-               size_t i, j, s = left->n_chan * sizeof(TYPE);\
-               TYPE v, *l, *r;\
-               for (i = 0; i < n; i += s) {\
-                       l = (TYPE *)(left->buf + i);\
-                       r = (TYPE *)(right->buf + i);\
-                       v = 0;\
-                       for (j = 0; j < left->n_chan; j++)\
-                               v += l[j] * r[j];\
-                       for (j = 0; j < left->n_chan; j++)\
-                               l[j] = v;\
-               }\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-dot-product.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -46,3 +30,23 @@ main(int argc, char *argv[])
        process_two_streams(&left, &right, STDOUT_FILENO, "<stdout>", process);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *left, struct stream *right, size_t n)
+{
+       size_t i, j, s = left->n_chan * sizeof(TYPE);
+       TYPE v, *l, *r;
+       for (i = 0; i < n; i += s) {
+               l = (TYPE *)(left->buf + i);
+               r = (TYPE *)(right->buf + i);
+               v = 0;
+               for (j = 0; j < left->n_chan; j++)
+                       v += l[j] * r[j];
+               for (j = 0; j < left->n_chan; j++)
+                       l[j] = v;
+       }
+}
+
+#endif
diff --git a/src/blind-double-sine-wave.c b/src/blind-double-sine-wave.c
index e10cf1e..0b009f3 100644
--- a/src/blind-double-sine-wave.c
+++ b/src/blind-double-sine-wave.c
@@ -1,47 +1,13 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-e]")
 
 static int equal = 0;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream)\
-       {\
-               size_t i, j, n;\
-               TYPE v, *p;\
-               do {\
-                       if (equal) {\
-                               n = stream->ptr / stream->pixel_size;\
-                               for (i = 0; i < n; i++) {\
-                                       p = (TYPE *)(stream->buf) + i * 
stream->n_chan;\
-                                       v = posmod(*p, (TYPE)2);\
-                                       v = v > 1 ? 2 - v : v;\
-                                       v = 1 - (sin(v * (2 * (TYPE)M_PI)) + 1) 
/ 2;\
-                                       for (j = 0; j < stream->n_chan; j++)\
-                                               p[j] = v;\
-                               }\
-                               n *= stream->pixel_size;\
-                       } else {\
-                               n = stream->ptr / stream->chan_size;\
-                               for (i = 0; i < n; i++) {\
-                                       p = (TYPE *)(stream->buf) + i;\
-                                       v = posmod(*p, (TYPE)2);\
-                                       v = v > 1 ? 2 - v : v;\
-                                       *p = 1 - (sin(v * (2 * (TYPE)M_PI)) + 
1) / 2;\
-                               }\
-                               n *= stream->chan_size;\
-                       }\
-                       ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");\
-                       memmove(stream->buf, stream->buf + n, stream->ptr -= 
n);\
-               } while (eread_stream(stream, SIZE_MAX));\
-               if (stream->ptr)\
-                       eprintf("%s: incomplete frame\n", stream->file);\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-double-sine-wave.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -74,3 +40,41 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       size_t i, j, n;
+       TYPE v, *p;
+       do {
+               if (equal) {
+                       n = stream->ptr / stream->pixel_size;
+                       for (i = 0; i < n; i++) {
+                               p = (TYPE *)(stream->buf) + i * stream->n_chan;
+                               v = posmod(*p, (TYPE)2);
+                               v = v > 1 ? 2 - v : v;
+                               v = 1 - (sin(v * (2 * (TYPE)M_PI)) + 1) / 2;
+                               for (j = 0; j < stream->n_chan; j++)
+                                       p[j] = v;
+                       }
+                       n *= stream->pixel_size;
+               } else {
+                       n = stream->ptr / stream->chan_size;
+                       for (i = 0; i < n; i++) {
+                               p = (TYPE *)(stream->buf) + i;
+                               v = posmod(*p, (TYPE)2);
+                               v = v > 1 ? 2 - v : v;
+                               *p = 1 - (sin(v * (2 * (TYPE)M_PI)) + 1) / 2;
+                       }
+                       n *= stream->chan_size;
+               }
+               ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");
+               memmove(stream->buf, stream->buf + n, stream->ptr -= n);
+       } while (eread_stream(stream, SIZE_MAX));
+       if (stream->ptr)
+               eprintf("%s: incomplete frame\n", stream->file);
+}
+
+#endif
diff --git a/src/blind-dual-key.c b/src/blind-dual-key.c
index 8dff71c..2394085 100644
--- a/src/blind-dual-key.c
+++ b/src/blind-dual-key.c
@@ -1,52 +1,13 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-m] X Y Z dual-X dual-Y dual-Z dual-stream")
 
 static double X1, Y1, Z1, X2, Y2, Z2;
 
-#define PROCESS(TYPE)\
-       do {\
-               size_t i;\
-               TYPE x1k = (TYPE)X1, y1k = (TYPE)Y1, z1k = (TYPE)Z1;\
-               TYPE x2k = (TYPE)X2, y2k = (TYPE)Y2, z2k = (TYPE)Z2;\
-               TYPE x1, y1, z1, a1, x2, y2, z2, a2;\
-               TYPE alpha, xalpha, yalpha, zalpha;\
-               for (i = 0; i < n; i += stream->pixel_size) {\
-                       x1 = ((TYPE *)(stream->buf + i))[0];\
-                       y1 = ((TYPE *)(stream->buf + i))[1];\
-                       z1 = ((TYPE *)(stream->buf + i))[2];\
-                       a1 = ((TYPE *)(stream->buf + i))[3];\
-                       x2 = ((TYPE *)(dual->buf + i))[0];\
-                       y2 = ((TYPE *)(dual->buf + i))[1];\
-                       z2 = ((TYPE *)(dual->buf + i))[2];\
-                       a2 = ((TYPE *)(dual->buf + i))[3];\
-                       if (x1 == x2 && y1 == y2 && z1 == z2) {\
-                               if (a1 != a2)\
-                                       ((TYPE *)(stream->buf + i))[3] = (a1 + 
a2) / 2;\
-                               continue;\
-                       }\
-                       xalpha = x1 == x2 ? (TYPE)0 : (x2 - x1 + x1k - x2k) / 
(x1k - x2k);\
-                       yalpha = y1 == y2 ? (TYPE)0 : (y2 - y1 + y1k - y2k) / 
(y1k - y2k);\
-                       zalpha = z1 == z2 ? (TYPE)0 : (z2 - z1 + z1k - z2k) / 
(z1k - z2k);\
-                       alpha = xalpha > yalpha ? xalpha : yalpha;\
-                       alpha = alpha  > zalpha ? alpha  : zalpha;\
-                       if (!alpha) {\
-                               ((TYPE *)(stream->buf + i))[0] = (TYPE)0;\
-                               ((TYPE *)(stream->buf + i))[1] = (TYPE)0;\
-                               ((TYPE *)(stream->buf + i))[2] = (TYPE)0;\
-                               ((TYPE *)(stream->buf + i))[3] = (TYPE)0;\
-                       } else {\
-                               ((TYPE *)(stream->buf + i))[0] = ((x1 - x1k + 
x2 - x2k) / alpha + x1k + x2k) / 2;\
-                               ((TYPE *)(stream->buf + i))[1] = ((y1 - y1k + 
y2 - y2k) / alpha + y1k + y2k) / 2;\
-                               ((TYPE *)(stream->buf + i))[2] = ((z1 - z1k + 
z2 - z2k) / alpha + z1k + z2k) / 2;\
-                               ((TYPE *)(stream->buf + i))[3] = (a1 + a2) / 2 
* alpha;\
-                       }\
-               }\
-       } while (0)
-
-static void process_lf(struct stream *stream, struct stream *dual, size_t n) 
{PROCESS(double);}
-static void process_f (struct stream *stream, struct stream *dual, size_t n) 
{PROCESS(float);}
+#define FILE "blind-dual-key.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -79,3 +40,48 @@ main(int argc, char *argv[])
        process_two_streams(&stream, &dual, STDOUT_FILENO, "<stdout>", process);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream, struct stream *dual, size_t n)
+{
+       size_t i;
+       TYPE x1k = (TYPE)X1, y1k = (TYPE)Y1, z1k = (TYPE)Z1;
+       TYPE x2k = (TYPE)X2, y2k = (TYPE)Y2, z2k = (TYPE)Z2;
+       TYPE x1, y1, z1, a1, x2, y2, z2, a2;
+       TYPE alpha, xalpha, yalpha, zalpha;
+       for (i = 0; i < n; i += stream->pixel_size) {
+               x1 = ((TYPE *)(stream->buf + i))[0];
+               y1 = ((TYPE *)(stream->buf + i))[1];
+               z1 = ((TYPE *)(stream->buf + i))[2];
+               a1 = ((TYPE *)(stream->buf + i))[3];
+               x2 = ((TYPE *)(dual->buf + i))[0];
+               y2 = ((TYPE *)(dual->buf + i))[1];
+               z2 = ((TYPE *)(dual->buf + i))[2];
+               a2 = ((TYPE *)(dual->buf + i))[3];
+               if (x1 == x2 && y1 == y2 && z1 == z2) {
+                       if (a1 != a2)
+                               ((TYPE *)(stream->buf + i))[3] = (a1 + a2) / 2;
+                       continue;
+               }
+               xalpha = x1 == x2 ? (TYPE)0 : (x2 - x1 + x1k - x2k) / (x1k - 
x2k);
+               yalpha = y1 == y2 ? (TYPE)0 : (y2 - y1 + y1k - y2k) / (y1k - 
y2k);
+               zalpha = z1 == z2 ? (TYPE)0 : (z2 - z1 + z1k - z2k) / (z1k - 
z2k);
+               alpha = xalpha > yalpha ? xalpha : yalpha;
+               alpha = alpha  > zalpha ? alpha  : zalpha;
+               if (!alpha) {
+                       ((TYPE *)(stream->buf + i))[0] = (TYPE)0;
+                       ((TYPE *)(stream->buf + i))[1] = (TYPE)0;
+                       ((TYPE *)(stream->buf + i))[2] = (TYPE)0;
+                       ((TYPE *)(stream->buf + i))[3] = (TYPE)0;
+               } else {
+                       ((TYPE *)(stream->buf + i))[0] = ((x1 - x1k + x2 - x2k) 
/ alpha + x1k + x2k) / 2;
+                       ((TYPE *)(stream->buf + i))[1] = ((y1 - y1k + y2 - y2k) 
/ alpha + y1k + y2k) / 2;
+                       ((TYPE *)(stream->buf + i))[2] = ((z1 - z1k + z2 - z2k) 
/ alpha + z1k + z2k) / 2;
+                       ((TYPE *)(stream->buf + i))[3] = (a1 + a2) / 2 * alpha;
+               }
+       }
+}
+
+#endif
diff --git a/src/blind-extract-alpha.c b/src/blind-extract-alpha.c
index f65042a..6b94c19 100644
--- a/src/blind-extract-alpha.c
+++ b/src/blind-extract-alpha.c
@@ -1,36 +1,11 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("colour-file")
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream, int fd, const char *fname)\
-       {\
-               char buf[sizeof(stream->buf)];\
-               size_t i, j, n;\
-               TYPE a, *p, *b;\
-               do {\
-                       n = stream->ptr / stream->pixel_size;\
-                       p = (TYPE *)(stream->buf) + stream->n_chan - 1;\
-                       b = (TYPE *)buf;\
-                       for (i = 0; i < n; i++, p += stream->n_chan) {\
-                               a = *p, *p = 1;\
-                               for (j = stream->n_chan - 1; j--;)\
-                                       *b++ = a;\
-                               *b++ = 1;\
-                       }\
-                       n *= stream->pixel_size;\
-                       ewriteall(fd, stream->buf, n, fname);\
-                       ewriteall(STDOUT_FILENO, buf, n, "<stdout>");\
-                       memmove(stream->buf, stream->buf + n, stream->ptr -= 
n);\
-               } while (eread_stream(stream, SIZE_MAX));\
-               if (stream->ptr)\
-                       eprintf("%s: incomplete frame\n", stream->file);\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-extract-alpha.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -59,3 +34,32 @@ main(int argc, char *argv[])
        process(&stream, fd, argv[0]);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream, int fd, const char *fname)
+{
+       char buf[sizeof(stream->buf)];
+       size_t i, j, n;
+       TYPE a, *p, *b;
+       do {
+               n = stream->ptr / stream->pixel_size;
+               p = (TYPE *)(stream->buf) + stream->n_chan - 1;
+               b = (TYPE *)buf;
+               for (i = 0; i < n; i++, p += stream->n_chan) {
+                       a = *p, *p = 1;
+                       for (j = stream->n_chan - 1; j--;)
+                               *b++ = a;
+                       *b++ = 1;
+               }
+               n *= stream->pixel_size;
+               ewriteall(fd, stream->buf, n, fname);
+               ewriteall(STDOUT_FILENO, buf, n, "<stdout>");
+               memmove(stream->buf, stream->buf + n, stream->ptr -= n);
+       } while (eread_stream(stream, SIZE_MAX));
+       if (stream->ptr)
+               eprintf("%s: incomplete frame\n", stream->file);
+}
+
+#endif
diff --git a/src/blind-invert-matrix.c b/src/blind-invert-matrix.c
index 9befe67..fb86cc1 100644
--- a/src/blind-invert-matrix.c
+++ b/src/blind-invert-matrix.c
@@ -1,62 +1,20 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("")
 
 static int equal = 0;
 
-#define SUB_ROWS()\
-       do {\
-               p2 = matrix + r2 * cn;\
-               t = p2[r1][0];\
-               for (c = 0; c < cn; c++)\
-                       p2[c][0] -= p1[c][0] * t;\
-       } while (0)
-
-#define PROCESS(TYPE)\
-       do {\
-               typedef TYPE pixel_t[4];\
-               size_t rn = stream->height, r1, r2, c;\
-               size_t cn = stream->width > rn ? stream->width : 2 * rn;\
-               pixel_t *matrix = buf, *p1, *p2;\
-               TYPE t;\
-               \
-               for (r1 = 0; r1 < rn; r1++) {\
-                       p1 = matrix + r1 * cn;\
-                       if (!p1[r1][0]) {\
-                               for (r2 = r1 + 1; r2 < rn; r2++) {\
-                                       p2 = matrix + r2 * cn;\
-                                       if (p2[r1][0])\
-                                               break;\
-                               }\
-                               if (r2 >= rn)\
-                                       eprintf("matrix is not invertable\n");\
-                               for (c = 0; c < cn; c++)\
-                                       t = p1[c][0], p1[c][0] = p2[c][0], 
p2[c][0] = t;\
-                       }\
-                       t = 1 / p1[r1][0];\
-                       for (c = 0; c < cn; c++)\
-                               p1[c][0] *= t;\
-                       for (r2 = r1 + 1; r2 < rn; r2++)\
-                               SUB_ROWS();\
-               }\
-               \
-               for (r1 = rn; r1--;) {\
-                       p1 = matrix + r1 * cn;\
-                       for (r2 = r1; r2--;)\
-                               SUB_ROWS();\
-               }\
-       } while (0)
-
-static void process_lf(struct stream *stream, void *buf) { PROCESS(double); }
-static void process_f (struct stream *stream, void *buf) { PROCESS(float); }
+#define FILE "blind-invert-matrix.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
 {
        struct stream stream;
-       size_t width, x, y, row_size;
-       char *buf, *one = alloca(4 * sizeof(double)), *p;
+       size_t width, x, y, i, row_size;
+       char *buf, *one, *p;
        void (*process)(struct stream *stream, void *buf);
 
        ARGBEGIN {
@@ -92,9 +50,8 @@ main(int argc, char *argv[])
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
        }
 
-       memcpy(one + 1 * stream.chan_size, one, stream.chan_size);
-       memcpy(one + 2 * stream.chan_size, one, stream.chan_size);
-       memcpy(one + 3 * stream.chan_size, one, stream.chan_size);
+       for (i = 1; i < stream.n_chan; i++)
+               memcpy(one + i * stream.chan_size, one, stream.chan_size);
 
        width = stream.width > stream.height ? stream.width : 2 * stream.height;
        buf = emalloc2(width, stream.col_size);
@@ -109,19 +66,17 @@ main(int argc, char *argv[])
                        }
                }
                if (equal) {
-                       process(&stream, buf + 1 * stream.chan_size);
+                       process(&stream, buf);
                        for (y = 0; y < stream.height; y++) {
                                for (x = 0; x < stream.width; x++) {
                                        p = buf + y * row_size + x * 
stream.pixel_size;
-                                       memcpy(p, p + stream.chan_size, 
stream.chan_size);
-                                       memcpy(p + 2 * stream.chan_size, p, 2 * 
stream.chan_size);
+                                       for (i = 1; i < stream.n_chan; i++)
+                                               memcpy(p + i * 
stream.chan_size, p, stream.chan_size);
                                }
                        }
                } else {
-                       process(&stream, buf + 0 * stream.chan_size);
-                       process(&stream, buf + 1 * stream.chan_size);
-                       process(&stream, buf + 2 * stream.chan_size);
-                       process(&stream, buf + 3 * stream.chan_size);
+                       for (i = 0; i < stream.n_chan; i++)
+                               process(&stream, buf + i * stream.chan_size);
                }
                for (y = 0; y < stream.height; y++)
                        ewriteall(STDOUT_FILENO, buf + y * row_size + 
stream.col_size, row_size - stream.col_size, "<stdout>");
@@ -130,3 +85,52 @@ main(int argc, char *argv[])
        free(buf);
        return 0;
 }
+
+#else
+
+#define SUB_ROWS()\
+       do {\
+               p2 = matrix + r2 * cn;\
+               t = p2[r1][0];\
+               for (c = 0; c < cn; c++)\
+                       p2[c][0] -= p1[c][0] * t;\
+       } while (0)
+
+static void
+PROCESS(struct stream *stream, void *buf)
+{
+       typedef TYPE pixel_t[4];
+       size_t rn = stream->height, r1, r2, c;
+       size_t cn = stream->width > rn ? stream->width : 2 * rn;
+       pixel_t *matrix = buf, *p1, *p2;
+       TYPE t;
+
+       for (r1 = 0; r1 < rn; r1++) {
+               p1 = matrix + r1 * cn;
+                       if (!p1[r1][0]) {
+                       for (r2 = r1 + 1; r2 < rn; r2++) {
+                               p2 = matrix + r2 * cn;
+                               if (p2[r1][0])
+                                       break;
+                       }
+                       if (r2 >= rn)
+                               eprintf("matrix is not invertable\n");
+                       for (c = 0; c < cn; c++)
+                               t = p1[c][0], p1[c][0] = p2[c][0], p2[c][0] = t;
+               }
+               t = 1 / p1[r1][0];
+               for (c = 0; c < cn; c++)
+                       p1[c][0] *= t;
+               for (r2 = r1 + 1; r2 < rn; r2++)
+                       SUB_ROWS();
+       }
+
+       for (r1 = rn; r1--;) {
+               p1 = matrix + r1 * cn;
+               for (r2 = r1; r2--;)
+                       SUB_ROWS();
+       }
+}
+
+#undef SUB_ROWS
+#endif
diff --git a/src/blind-linear-gradient.c b/src/blind-linear-gradient.c
index 1865ae6..57cde3c 100644
--- a/src/blind-linear-gradient.c
+++ b/src/blind-linear-gradient.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-b] -w width -h height")
@@ -7,53 +8,8 @@ static int bilinear = 0;
 static size_t width = 0;
 static size_t height = 0;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream)\
-       {\
-               typedef TYPE pixel_t[4];\
-               pixel_t buf[BUFSIZ / sizeof(pixel_t)];\
-               TYPE *params, x1, y1, x2, y2, norm2;\
-               TYPE x, y;\
-               size_t ix, iy, ptr = 0;\
-               for (;;) {\
-                       while (stream->ptr < stream->frame_size) {\
-                               if (!eread_stream(stream, stream->frame_size - 
stream->ptr)) {\
-                                       ewriteall(STDOUT_FILENO, buf, ptr * 
sizeof(*buf), "<stdout>");\
-                                       return;\
-                               }\
-                       }\
-                       params = (TYPE *)stream->buf;\
-                       x1 = (params)[0];\
-                       y1 = (params)[1];\
-                       x2 = (params)[4];\
-                       y2 = (params)[5];\
-                       memmove(stream->buf, stream->buf + stream->frame_size,\
-                               stream->ptr -= stream->frame_size);\
-                       \
-                       x2 -= x1;\
-                       y2 -= y1;\
-                       norm2 = x2 * x2 + y2 * y2;\
-                       \
-                       for (iy = 0; iy < height; iy++) {\
-                               y = (TYPE)iy - y1;\
-                               for (ix = 0; ix < width; ix++) {\
-                                       x = (TYPE)ix - x1;\
-                                       x = (x * x2 + y * y2) / norm2;\
-                                       if (bilinear)\
-                                               x = abs(x);\
-                                       buf[ptr][0] = buf[ptr][1] = buf[ptr][2] 
= buf[ptr][3] = x;\
-                                       if (++ptr == ELEMENTSOF(buf)) {\
-                                               ewriteall(STDOUT_FILENO, buf, 
sizeof(buf), "<stdout>");\
-                                               ptr = 0;\
-                                       }\
-                               }\
-                       }\
-               }\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-linear-gradient.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -97,3 +53,52 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       typedef TYPE pixel_t[4];
+       pixel_t buf[BUFSIZ / sizeof(pixel_t)];
+       TYPE *params, x1, y1, x2, y2, norm2;
+       TYPE x, y;
+       size_t ix, iy, ptr = 0;
+
+       for (;;) {
+               while (stream->ptr < stream->frame_size) {
+                       if (!eread_stream(stream, stream->frame_size - 
stream->ptr)) {
+                               ewriteall(STDOUT_FILENO, buf, ptr * 
sizeof(*buf), "<stdout>");
+                               return;
+                       }
+               }
+               params = (TYPE *)stream->buf;
+               x1 = (params)[0];
+               y1 = (params)[1];
+               x2 = (params)[4];
+               y2 = (params)[5];
+               memmove(stream->buf, stream->buf + stream->frame_size,
+                       stream->ptr -= stream->frame_size);
+
+               x2 -= x1;
+               y2 -= y1;
+               norm2 = x2 * x2 + y2 * y2;
+
+               for (iy = 0; iy < height; iy++) {
+                       y = (TYPE)iy - y1;
+                       for (ix = 0; ix < width; ix++) {
+                               x = (TYPE)ix - x1;
+                               x = (x * x2 + y * y2) / norm2;
+                               if (bilinear)
+                                       x = abs(x);
+                               buf[ptr][0] = buf[ptr][1] = buf[ptr][2] = 
buf[ptr][3] = x;
+                               if (++ptr == ELEMENTSOF(buf)) {
+                                       ewriteall(STDOUT_FILENO, buf, 
sizeof(buf), "<stdout>");
+                                       ptr = 0;
+                               }
+                       }
+               }
+       }
+}
+
+#endif
diff --git a/src/blind-matrix-orthoproject.c b/src/blind-matrix-orthoproject.c
index 4a9cb3c..5bac543 100644
--- a/src/blind-matrix-orthoproject.c
+++ b/src/blind-matrix-orthoproject.c
@@ -1,56 +1,13 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-c]")
 
 static int per_channel = 0;
 
-#define PROCESS(TYPE)\
-       do {\
-               typedef TYPE pixel_t[4];\
-               pixel_t matrix[9];\
-               pixel_t buf[2];\
-               TYPE x2, y2, norm2;\
-               size_t i;\
-               \
-               for (i = 0; i < stream->n_chan; i++) {\
-                       matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\
-                       matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\
-                       matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\
-               }\
-               \
-               while (eread_frame(stream, buf)) {\
-                       if (per_channel) {\
-                               for (i = 0; i < stream->n_chan; i++) {\
-                                       x2 = buf[0][i] * buf[0][i];\
-                                       y2 = buf[1][i] * buf[1][i];\
-                                       norm2 = x2 + y2;\
-                                       matrix[0][i] = x2 / norm2;\
-                                       matrix[4][i] = y2 / norm2;\
-                                       matrix[3][i] = matrix[1][i] = buf[0][i] 
* buf[1][i] / norm2;\
-                               }\
-                       } else {\
-                               buf[0][1] *= buf[0][3];\
-                               buf[1][1] *= buf[1][3];\
-                               x2 = buf[0][1] * buf[0][1];\
-                               y2 = buf[1][1] * buf[1][1];\
-                               norm2 = x2 + y2;\
-                               matrix[0][0] = x2 / norm2;\
-                               matrix[4][0] = y2 / norm2;\
-                               matrix[3][0] = matrix[1][0] = buf[0][1] * 
buf[1][1] / norm2;\
-                               for (i = 1; i < stream->n_chan; i++) {\
-                                       matrix[0][i] = matrix[0][0];\
-                                       matrix[1][i] = matrix[1][0];\
-                                       matrix[3][i] = matrix[3][0];\
-                                       matrix[4][i] = matrix[4][0];\
-                               }\
-                       }\
-                       ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), 
"<stdout>");\
-               }\
-       } while (0)
-
-static void process_lf(struct stream *stream) { PROCESS(double); }
-static void process_f(struct stream *stream) { PROCESS(float); }
+#define FILE "blind-matrix-orthoproject.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -89,3 +46,52 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       typedef TYPE pixel_t[4];
+       pixel_t matrix[9];
+       pixel_t buf[2];
+       TYPE x2, y2, norm2;
+       size_t i;
+
+       for (i = 0; i < stream->n_chan; i++) {
+               matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;
+               matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;
+               matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;
+       }
+
+       while (eread_frame(stream, buf)) {
+               if (per_channel) {
+                       for (i = 0; i < stream->n_chan; i++) {
+                               x2 = buf[0][i] * buf[0][i];
+                               y2 = buf[1][i] * buf[1][i];
+                               norm2 = x2 + y2;
+                               matrix[0][i] = x2 / norm2;
+                               matrix[4][i] = y2 / norm2;
+                               matrix[3][i] = matrix[1][i] = buf[0][i] * 
buf[1][i] / norm2;
+                       }
+               } else {
+                       buf[0][1] *= buf[0][3];
+                       buf[1][1] *= buf[1][3];
+                       x2 = buf[0][1] * buf[0][1];
+                       y2 = buf[1][1] * buf[1][1];
+                       norm2 = x2 + y2;
+                       matrix[0][0] = x2 / norm2;
+                       matrix[4][0] = y2 / norm2;
+                       matrix[3][0] = matrix[1][0] = buf[0][1] * buf[1][1] / 
norm2;
+                       for (i = 1; i < stream->n_chan; i++) {
+                               matrix[0][i] = matrix[0][0];
+                               matrix[1][i] = matrix[1][0];
+                               matrix[3][i] = matrix[3][0];
+                               matrix[4][i] = matrix[4][0];
+                       }
+               }
+               ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");
+       }
+}
+
+#endif
diff --git a/src/blind-matrix-reflect.c b/src/blind-matrix-reflect.c
index ef882b5..45f6ed8 100644
--- a/src/blind-matrix-reflect.c
+++ b/src/blind-matrix-reflect.c
@@ -1,54 +1,13 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-c]")
 
 static int per_channel = 0;
 
-#define PROCESS(TYPE)\
-       do {\
-               typedef TYPE pixel_t[4];\
-               pixel_t matrix[9];\
-               pixel_t buf[2];\
-               TYPE x2, y2, norm2;\
-               size_t i;\
-               \
-               for (i = 0; i < stream->n_chan; i++) {\
-                       matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\
-                       matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\
-                       matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\
-               }\
-               \
-               while (eread_frame(stream, buf)) {\
-                       if (per_channel) {\
-                               for (i = 0; i < stream->n_chan; i++) {\
-                                       x2 = buf[0][i] * buf[0][i];\
-                                       y2 = buf[1][i] * buf[1][i];\
-                                       norm2 = x2 + y2;\
-                                       matrix[4][i] = -(matrix[0][i] = (x2 - 
y2) / norm2);\
-                                       matrix[3][i] = matrix[1][i] = 2 * 
buf[0][i] * buf[1][i] / norm2;\
-                               }\
-                       } else {\
-                               buf[0][1] *= buf[0][3];\
-                               buf[1][1] *= buf[1][3];\
-                               x2 = buf[0][1] * buf[0][1];\
-                               y2 = buf[1][1] * buf[1][1];\
-                               norm2 = x2 + y2;\
-                               matrix[4][0] = -(matrix[0][0] = (x2 - y2) / 
norm2);\
-                               matrix[3][0] = matrix[1][0] = 2 * buf[0][1] * 
buf[1][1] / norm2;\
-                               for (i = 1; i < stream->n_chan; i++) {\
-                                       matrix[0][i] = matrix[0][0];\
-                                       matrix[1][i] = matrix[1][0];\
-                                       matrix[3][i] = matrix[3][0];\
-                                       matrix[4][i] = matrix[4][0];\
-                               }\
-                       }\
-                       ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), 
"<stdout>");\
-               }\
-       } while (0)
-
-static void process_lf(struct stream *stream) { PROCESS(double); }
-static void process_f(struct stream *stream) { PROCESS(float); }
+#define FILE "blind-matrix-reflect.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -87,3 +46,50 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       typedef TYPE pixel_t[4];
+       pixel_t matrix[9];
+       pixel_t buf[2];
+       TYPE x2, y2, norm2;
+       size_t i;
+
+       for (i = 0; i < stream->n_chan; i++) {
+               matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;
+               matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;
+               matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;
+       }
+
+       while (eread_frame(stream, buf)) {
+               if (per_channel) {
+                       for (i = 0; i < stream->n_chan; i++) {
+                               x2 = buf[0][i] * buf[0][i];
+                               y2 = buf[1][i] * buf[1][i];
+                               norm2 = x2 + y2;
+                               matrix[4][i] = -(matrix[0][i] = (x2 - y2) / 
norm2);
+                               matrix[3][i] = matrix[1][i] = 2 * buf[0][i] * 
buf[1][i] / norm2;
+                       }
+               } else {
+                       buf[0][1] *= buf[0][3];
+                       buf[1][1] *= buf[1][3];
+                       x2 = buf[0][1] * buf[0][1];
+                       y2 = buf[1][1] * buf[1][1];
+                       norm2 = x2 + y2;
+                       matrix[4][0] = -(matrix[0][0] = (x2 - y2) / norm2);
+                       matrix[3][0] = matrix[1][0] = 2 * buf[0][1] * buf[1][1] 
/ norm2;
+                       for (i = 1; i < stream->n_chan; i++) {
+                               matrix[0][i] = matrix[0][0];
+                               matrix[1][i] = matrix[1][0];
+                               matrix[3][i] = matrix[3][0];
+                               matrix[4][i] = matrix[4][0];
+                       }
+               }
+               ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");
+       }
+}
+
+#endif
diff --git a/src/blind-matrix-rotate.c b/src/blind-matrix-rotate.c
index 486616e..f629df0 100644
--- a/src/blind-matrix-rotate.c
+++ b/src/blind-matrix-rotate.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-cd]")
@@ -6,52 +7,8 @@ USAGE("[-cd]")
 static int per_channel = 0;
 static int in_degrees = 0;
 
-#define PROCESS(TYPE)\
-       do {\
-               typedef TYPE pixel_t[4];\
-               pixel_t matrix[9];\
-               pixel_t buf;\
-               size_t i;\
-               \
-               for (i = 0; i < stream->n_chan; i++) {\
-                       matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\
-                       matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\
-                       matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\
-               }\
-               \
-               while (eread_frame(stream, buf)) {\
-                       if (per_channel && in_degrees) {\
-                               for (i = 0; i < stream->n_chan; i++) {\
-                                       matrix[4][i] = matrix[0][i] = 
degcos(buf[i]);\
-                                       matrix[3][i] = -(matrix[1][i] = 
degsin(buf[i]));\
-                               }\
-                       } else if (per_channel) {\
-                               for (i = 0; i < stream->n_chan; i++) {\
-                                       matrix[4][i] = matrix[0][i] = 
cos(buf[i]);\
-                                       matrix[3][i] = -(matrix[1][i] = 
sin(buf[i]));\
-                               }\
-                       } else {\
-                               buf[1] *= buf[3];\
-                               if (in_degrees) {\
-                                       matrix[4][0] = matrix[0][0] = 
degcos(buf[1]);\
-                                       matrix[3][0] = -(matrix[1][0] = 
degsin(buf[1]));\
-                               } else {\
-                                       matrix[4][0] = matrix[0][0] = 
cos(buf[1]);\
-                                       matrix[3][0] = -(matrix[1][0] = 
sin(buf[1]));\
-                               }\
-                               for (i = 0; i < stream->n_chan; i++) {\
-                                       matrix[0][i] = matrix[0][0];\
-                                       matrix[1][i] = matrix[1][0];\
-                                       matrix[3][i] = matrix[3][0];\
-                                       matrix[4][i] = matrix[4][0];\
-                               }\
-                       }\
-                       ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), 
"<stdout>");\
-               }\
-       } while (0)
-
-static void process_lf(struct stream *stream) { PROCESS(double); }
-static void process_f(struct stream *stream) { PROCESS(float); }
+#define FILE "blind-matrix-rotate.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -93,3 +50,52 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       typedef TYPE pixel_t[4];
+       pixel_t matrix[9];
+       pixel_t buf;
+       size_t i;
+
+       for (i = 0; i < stream->n_chan; i++) {
+               matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;
+               matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;
+               matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;
+       }
+
+       while (eread_frame(stream, buf)) {
+               if (per_channel && in_degrees) {
+                       for (i = 0; i < stream->n_chan; i++) {
+                               matrix[4][i] = matrix[0][i] = degcos(buf[i]);
+                               matrix[3][i] = -(matrix[1][i] = degsin(buf[i]));
+                       }
+               } else if (per_channel) {
+                       for (i = 0; i < stream->n_chan; i++) {
+                               matrix[4][i] = matrix[0][i] = cos(buf[i]);
+                               matrix[3][i] = -(matrix[1][i] = sin(buf[i]));
+                       }
+               } else {
+                       buf[1] *= buf[3];
+                       if (in_degrees) {
+                               matrix[4][0] = matrix[0][0] = degcos(buf[1]);
+                               matrix[3][0] = -(matrix[1][0] = degsin(buf[1]));
+                       } else {
+                               matrix[4][0] = matrix[0][0] = cos(buf[1]);
+                               matrix[3][0] = -(matrix[1][0] = sin(buf[1]));
+                       }
+                       for (i = 0; i < stream->n_chan; i++) {
+                               matrix[0][i] = matrix[0][0];
+                               matrix[1][i] = matrix[1][0];
+                               matrix[3][i] = matrix[3][0];
+                               matrix[4][i] = matrix[4][0];
+                       }
+               }
+               ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");
+       }
+}
+
+#endif
diff --git a/src/blind-matrix-scale.c b/src/blind-matrix-scale.c
index 5675a8e..9c5326f 100644
--- a/src/blind-matrix-scale.c
+++ b/src/blind-matrix-scale.c
@@ -1,43 +1,13 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-c]")
 
 static int per_channel = 0;
 
-#define PROCESS(TYPE)\
-       do {\
-               typedef TYPE pixel_t[4];\
-               pixel_t matrix[9];\
-               pixel_t buf[2];\
-               size_t i;\
-               \
-               for (i = 0; i < stream->n_chan; i++) {\
-                       matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\
-                       matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\
-                       matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\
-               }\
-               \
-               while (eread_frame(stream, buf)) {\
-                       if (per_channel) {\
-                               for (i = 0; i < stream->n_chan; i++) {\
-                                       matrix[0][i] = buf[0][i];\
-                                       matrix[4][i] = buf[1][i];\
-                               }\
-                       } else {\
-                               buf[0][1] *= buf[0][3];\
-                               buf[1][1] *= buf[1][3];\
-                               for (i = 0; i < stream->n_chan; i++) {\
-                                       matrix[0][i] = buf[0][1];\
-                                       matrix[4][i] = buf[1][1];\
-                               }\
-                       }\
-                       ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), 
"<stdout>");\
-               }\
-       } while (0)
-
-static void process_lf(struct stream *stream) { PROCESS(double); }
-static void process_f(struct stream *stream) { PROCESS(float); }
+#define FILE "blind-matrix-scale.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -76,3 +46,39 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       typedef TYPE pixel_t[4];
+       pixel_t matrix[9];
+       pixel_t buf[2];
+       size_t i;
+
+       for (i = 0; i < stream->n_chan; i++) {
+               matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;
+               matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;
+               matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;
+       }
+
+       while (eread_frame(stream, buf)) {
+               if (per_channel) {
+                       for (i = 0; i < stream->n_chan; i++) {
+                               matrix[0][i] = buf[0][i];
+                               matrix[4][i] = buf[1][i];
+                       }
+               } else {
+                       buf[0][1] *= buf[0][3];
+                       buf[1][1] *= buf[1][3];
+                       for (i = 0; i < stream->n_chan; i++) {
+                               matrix[0][i] = buf[0][1];
+                               matrix[4][i] = buf[1][1];
+                       }
+               }
+               ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");
+       }
+}
+
+#endif
diff --git a/src/blind-matrix-shear.c b/src/blind-matrix-shear.c
index e6a7d2d..d8ab02c 100644
--- a/src/blind-matrix-shear.c
+++ b/src/blind-matrix-shear.c
@@ -1,52 +1,15 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
-USAGE("[-a [-d]][c]")
+USAGE("[-a [-d]] [-c]")
 
 static int by_angle = 0;
 static int per_channel = 0;
 static int in_degrees = 0;
 
-#define PROCESS(TYPE)\
-       do {\
-               typedef TYPE pixel_t[4];\
-               pixel_t matrix[9];\
-               pixel_t buf[2];\
-               TYPE conv = in_degrees ? (TYPE)(M_PI / 180.) : 1;\
-               size_t i;\
-               \
-               for (i = 0; i < stream->n_chan; i++) {\
-                       matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\
-                       matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\
-                       matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\
-               }\
-               \
-               while (eread_frame(stream, buf)) {\
-                       if (by_angle) {\
-                               for (i = !per_channel; i < (per_channel ? 
stream->n_chan : 2); i++) {\
-                                       buf[0][i] = tan(buf[0][i] * conv);\
-                                       buf[1][i] = tan(buf[1][i] * conv);\
-                               }\
-                       }\
-                       if (per_channel) {\
-                               for (i = 0; i < stream->n_chan; i++) {\
-                                       matrix[1][i] = buf[0][i];\
-                                       matrix[3][i] = buf[1][i];\
-                               }\
-                       } else {\
-                               buf[0][1] *= buf[0][3];\
-                               buf[1][1] *= buf[1][3];\
-                               for (i = 0; i < stream->n_chan; i++) {\
-                                       matrix[1][i] = buf[0][1];\
-                                       matrix[3][i] = buf[1][1];\
-                               }\
-                       }\
-                       ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), 
"<stdout>");\
-               }\
-       } while (0)
-
-static void process_lf(struct stream *stream) { PROCESS(double); }
-static void process_f(struct stream *stream) { PROCESS(float); }
+#define FILE "blind-matrix-shear.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -91,3 +54,46 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       typedef TYPE pixel_t[4];
+       pixel_t matrix[9];
+       pixel_t buf[2];
+       TYPE conv = in_degrees ? (TYPE)(M_PI / 180.) : 1;
+       size_t i;
+
+       for (i = 0; i < stream->n_chan; i++) {
+               matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;
+               matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;
+               matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;
+       }
+
+       while (eread_frame(stream, buf)) {
+               if (by_angle) {
+                       for (i = !per_channel; i < (per_channel ? 
stream->n_chan : 2); i++) {
+                               buf[0][i] = tan(buf[0][i] * conv);
+                               buf[1][i] = tan(buf[1][i] * conv);
+                       }
+               }
+               if (per_channel) {
+                       for (i = 0; i < stream->n_chan; i++) {
+                               matrix[1][i] = buf[0][i];
+                               matrix[3][i] = buf[1][i];
+                       }
+               } else {
+                       buf[0][1] *= buf[0][3];
+                       buf[1][1] *= buf[1][3];
+                       for (i = 0; i < stream->n_chan; i++) {
+                               matrix[1][i] = buf[0][1];
+                               matrix[3][i] = buf[1][1];
+                       }
+               }
+               ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");
+       }
+}
+
+#endif
diff --git a/src/blind-matrix-translate.c b/src/blind-matrix-translate.c
index d062615..beb84d9 100644
--- a/src/blind-matrix-translate.c
+++ b/src/blind-matrix-translate.c
@@ -1,43 +1,13 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-c]")
 
 static int per_channel = 0;
 
-#define PROCESS(TYPE)\
-       do {\
-               typedef TYPE pixel_t[4];\
-               pixel_t matrix[9];\
-               pixel_t buf[2];\
-               size_t i;\
-               \
-               for (i = 0; i < stream->n_chan; i++) {\
-                       matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\
-                       matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\
-                       matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\
-               }\
-               \
-               while (eread_frame(stream, buf)) {\
-                       if (per_channel) {\
-                               for (i = 0; i < stream->n_chan; i++) {\
-                                       matrix[2][i] = buf[0][i];\
-                                       matrix[5][i] = buf[1][i];\
-                               }\
-                       } else {\
-                               buf[0][1] *= buf[0][3];\
-                               buf[1][1] *= buf[1][3];\
-                               for (i = 0; i < stream->n_chan; i++) {\
-                                       matrix[2][i] = buf[0][1];\
-                                       matrix[5][i] = buf[1][1];\
-                               }\
-                       }\
-                       ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), 
"<stdout>");\
-               }\
-       } while (0)
-
-static void process_lf(struct stream *stream) { PROCESS(double); }
-static void process_f(struct stream *stream) { PROCESS(float); }
+#define FILE "blind-matrix-translate.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -76,3 +46,39 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       typedef TYPE pixel_t[4];
+       pixel_t matrix[9];
+       pixel_t buf[2];
+       size_t i;
+
+       for (i = 0; i < stream->n_chan; i++) {
+               matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;
+               matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;
+               matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;
+       }
+
+       while (eread_frame(stream, buf)) {
+               if (per_channel) {
+                       for (i = 0; i < stream->n_chan; i++) {
+                               matrix[2][i] = buf[0][i];
+                               matrix[5][i] = buf[1][i];
+                       }
+               } else {
+                       buf[0][1] *= buf[0][3];
+                       buf[1][1] *= buf[1][3];
+                       for (i = 0; i < stream->n_chan; i++) {
+                               matrix[2][i] = buf[0][1];
+                               matrix[5][i] = buf[1][1];
+                       }
+               }
+               ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");
+       }
+}
+
+#endif
diff --git a/src/blind-matrix-transpose.c b/src/blind-matrix-transpose.c
index f24d0a7..2634b8f 100644
--- a/src/blind-matrix-transpose.c
+++ b/src/blind-matrix-transpose.c
@@ -1,42 +1,13 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-c]")
 
 static int per_channel = 0;
 
-#define PROCESS(TYPE)\
-       do {\
-               typedef TYPE pixel_t[4];\
-               pixel_t matrix[9];\
-               pixel_t buf;\
-               size_t i;\
-               \
-               for (i = 0; i < stream->n_chan; i++) {\
-                       matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\
-                       matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\
-                       matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\
-               }\
-               \
-               while (eread_frame(stream, buf)) {\
-                       if (per_channel) {\
-                               for (i = 0; i < stream->n_chan; i++) {\
-                                       matrix[3][i] = matrix[1][i] = buf[i];\
-                                       matrix[4][i] = matrix[0][i] = 1 - 
buf[i];\
-                               }\
-                       } else {\
-                               buf[1] *= buf[3];\
-                               for (i = 0; i < stream->n_chan; i++) {\
-                                       matrix[3][i] = matrix[1][i] = buf[1];\
-                                       matrix[4][i] = matrix[0][i] = 1 - 
matrix[3][i];\
-                               }\
-                       }\
-                       ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), 
"<stdout>");\
-               }\
-       } while (0)
-
-static void process_lf(struct stream *stream) { PROCESS(double); }
-static void process_f(struct stream *stream) { PROCESS(float); }
+#define FILE "blind-matrix-transpose.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -75,3 +46,38 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       typedef TYPE pixel_t[4];
+       pixel_t matrix[9];
+       pixel_t buf;
+       size_t i;
+
+       for (i = 0; i < stream->n_chan; i++) {
+               matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;
+               matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;
+               matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;
+       }
+
+       while (eread_frame(stream, buf)) {
+               if (per_channel) {
+                       for (i = 0; i < stream->n_chan; i++) {
+                               matrix[3][i] = matrix[1][i] = buf[i];
+                               matrix[4][i] = matrix[0][i] = 1 - buf[i];
+                       }
+               } else {
+                       buf[1] *= buf[3];
+                       for (i = 0; i < stream->n_chan; i++) {
+                               matrix[3][i] = matrix[1][i] = buf[1];
+                               matrix[4][i] = matrix[0][i] = 1 - matrix[3][i];
+                       }
+               }
+               ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");
+       }
+}
+
+#endif
diff --git a/src/blind-multiply-matrices.c b/src/blind-multiply-matrices.c
index 5c70d4b..6aea2f0 100644
--- a/src/blind-multiply-matrices.c
+++ b/src/blind-multiply-matrices.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-en] leftmost-stream ... rightmost-stream")
@@ -6,56 +7,8 @@ USAGE("[-en] leftmost-stream ... rightmost-stream")
 static int equal = 0;
 static size_t max_frame_size;
 
-#define PROCESS(TYPE)\
-       do {\
-               typedef TYPE pixel_t[4];\
-               pixel_t *res, *left, *right, *tmp;\
-               size_t i, j, w, h, h2, x, y, k, r;\
-               res = emalloc(max_frame_size);\
-               left = emalloc(max_frame_size);\
-               right = emalloc(max_frame_size);\
-               \
-               while (eread_frame(streams + (n_streams - 1), res)) {\
-                       w = streams[n_streams - 1].width;\
-                       h = streams[n_streams - 1].height;\
-                       for (i = n_streams - 1; i--;) {\
-                               tmp = res, res = right, right = tmp;\
-                               if (!eread_frame(streams + i, left))\
-                                       goto done;\
-                               h2 = streams[i].height;\
-                               memset(res, 0, w * h2 * streams->pixel_size);\
-                               \
-                               /* XXX Is there any significant performance to 
be gained by transposing `right`? */\
-                               if (equal) {\
-                                       for (y = r = 0; y < h2; y++) {\
-                                               for (x = 0; x < w; x++, r++) {\
-                                                       for (k = 0; k < h; k++) 
\
-                                                               res[r][0] += 
left[y * h + k][0] * right[k * w + x][0];\
-                                                       for (j = 1; j < 
streams->n_chan; j++)\
-                                                               res[r][j] = 
res[r][0];\
-                                               }\
-                                       }\
-                               } else {\
-                                       for (y = r = 0; y < h2; y++)\
-                                               for (x = 0; x < w; x++, r++) \
-                                                       for (k = 0; k < h; k++)\
-                                                               for (j = 0; j < 
streams->n_chan; j++)\
-                                                                       
res[r][j] += left[y * h + k][j] * right[k * w + x][j];\
-                               }\
-                               \
-                               h = h2;\
-                       }\
-                       ewriteall(STDOUT_FILENO, res, streams->frame_size, 
"<stdout>");\
-               }\
-               \
-       done:\
-               free(res);\
-               free(left);\
-               free(right);\
-       } while (0)
-
-static void process_lf(struct stream *streams, size_t n_streams) { 
PROCESS(double); }
-static void process_f (struct stream *streams, size_t n_streams) { 
PROCESS(float); }
+#define FILE "blind-multiply-matrices.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -137,3 +90,56 @@ main(int argc, char *argv[])
        free(streams);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *streams, size_t n_streams)
+{
+       typedef TYPE pixel_t[4];
+       pixel_t *res, *left, *right, *tmp;
+       size_t i, j, w, h, h2, x, y, k, r;
+       res = emalloc(max_frame_size);
+       left = emalloc(max_frame_size);
+       right = emalloc(max_frame_size);
+
+       while (eread_frame(streams + (n_streams - 1), res)) {
+               w = streams[n_streams - 1].width;
+               h = streams[n_streams - 1].height;
+               for (i = n_streams - 1; i--;) {
+                       tmp = res, res = right, right = tmp;
+                       if (!eread_frame(streams + i, left))
+                               goto done;
+                       h2 = streams[i].height;
+                       memset(res, 0, w * h2 * streams->pixel_size);
+
+                       /* XXX Is there any significant performance to be 
gained by transposing `right`? */
+                       if (equal) {
+                               for (y = r = 0; y < h2; y++) {
+                                       for (x = 0; x < w; x++, r++) {
+                                               for (k = 0; k < h; k++)
+                                                       res[r][0] += left[y * h 
+ k][0] * right[k * w + x][0];
+                                               for (j = 1; j < 
streams->n_chan; j++)
+                                                       res[r][j] = res[r][0];
+                                       }
+                               }
+                       } else {
+                               for (y = r = 0; y < h2; y++)
+                                       for (x = 0; x < w; x++, r++)
+                                               for (k = 0; k < h; k++)
+                                                       for (j = 0; j < 
streams->n_chan; j++)
+                                                               res[r][j] += 
left[y * h + k][j] * right[k * w + x][j];
+                       }
+
+                       h = h2;
+               }
+               ewriteall(STDOUT_FILENO, res, streams->frame_size, "<stdout>");
+       }
+
+done:
+       free(res);
+       free(left);
+       free(right);
+}
+
+#endif
diff --git a/src/blind-norm.c b/src/blind-norm.c
index 13db67c..8a2b223 100644
--- a/src/blind-norm.c
+++ b/src/blind-norm.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-axyz]")
@@ -8,39 +9,8 @@ static int skip_x = 0;
 static int skip_y = 0;
 static int skip_z = 0;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream)\
-       {\
-               size_t i, n;\
-               TYPE x, y, z, a, norm;\
-               do {\
-                       n = stream->ptr / stream->pixel_size;\
-                       for (i = 0; i < n; i++) {\
-                               x = ((TYPE *)(stream->buf))[4 * i + 0];\
-                               y = ((TYPE *)(stream->buf))[4 * i + 1];\
-                               z = ((TYPE *)(stream->buf))[4 * i + 2];\
-                               a = ((TYPE *)(stream->buf))[4 * i + 3];\
-                               norm = sqrt(x * x + y * y + z * z + a * a);\
-                               if (!skip_x)\
-                                       ((TYPE *)(stream->buf))[4 * i + 0] = 
norm;\
-                               if (!skip_y)\
-                                       ((TYPE *)(stream->buf))[4 * i + 1] = 
norm;\
-                               if (!skip_z)\
-                                       ((TYPE *)(stream->buf))[4 * i + 2] = 
norm;\
-                               if (!skip_a)\
-                                       ((TYPE *)(stream->buf))[4 * i + 3] = 
norm;\
-                       }\
-                       n *= stream->pixel_size;\
-                       ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");\
-                       memmove(stream->buf, stream->buf + n, stream->ptr -= 
n);\
-               } while (eread_stream(stream, SIZE_MAX));\
-               if (stream->ptr)\
-                       eprintf("%s: incomplete frame\n", stream->file);\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-norm.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -82,3 +52,37 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       size_t i, n;
+       TYPE x, y, z, a, norm;\
+       do {
+               n = stream->ptr / stream->pixel_size;
+               for (i = 0; i < n; i++) {
+                       x = ((TYPE *)(stream->buf))[4 * i + 0];
+                       y = ((TYPE *)(stream->buf))[4 * i + 1];
+                       z = ((TYPE *)(stream->buf))[4 * i + 2];
+                       a = ((TYPE *)(stream->buf))[4 * i + 3];
+                       norm = sqrt(x * x + y * y + z * z + a * a);
+                       if (!skip_x)
+                               ((TYPE *)(stream->buf))[4 * i + 0] = norm;
+                       if (!skip_y)
+                               ((TYPE *)(stream->buf))[4 * i + 1] = norm;
+                       if (!skip_z)
+                               ((TYPE *)(stream->buf))[4 * i + 2] = norm;
+                       if (!skip_a)
+                               ((TYPE *)(stream->buf))[4 * i + 3] = norm;
+               }
+               n *= stream->pixel_size;
+               ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");
+               memmove(stream->buf, stream->buf + n, stream->ptr -= n);
+       } while (eread_stream(stream, SIZE_MAX));
+       if (stream->ptr)
+               eprintf("%s: incomplete frame\n", stream->file);
+}
+
+#endif
diff --git a/src/blind-premultiply.c b/src/blind-premultiply.c
index 3d9065a..5d46c06 100644
--- a/src/blind-premultiply.c
+++ b/src/blind-premultiply.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-xyz]")
@@ -7,33 +8,8 @@ static int skip_x = 0;
 static int skip_y = 0;
 static int skip_z = 0;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream)\
-       {\
-               size_t i, n;\
-               TYPE a;\
-               do {\
-                       n = stream->ptr / stream->pixel_size;\
-                       for (i = 0; i < n; i++) {\
-                               a = ((TYPE *)(stream->buf))[4 * i + 3];\
-                               if (!skip_x)\
-                                       ((TYPE *)(stream->buf))[4 * i + 0] *= 
a;\
-                               if (!skip_y)\
-                                       ((TYPE *)(stream->buf))[4 * i + 1] *= 
a;\
-                               if (!skip_z)\
-                                       ((TYPE *)(stream->buf))[4 * i + 2] *= 
a;\
-                       }\
-                       n *= stream->pixel_size;\
-                       ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");\
-                       memmove(stream->buf, stream->buf + n, stream->ptr -= 
n);\
-               } while (eread_stream(stream, SIZE_MAX));\
-               if (stream->ptr)\
-                       eprintf("%s: incomplete frame\n", stream->file);\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-premultiply.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -72,3 +48,31 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       size_t i, n;
+       TYPE a;
+       do {
+               n = stream->ptr / stream->pixel_size;
+               for (i = 0; i < n; i++) {
+                       a = ((TYPE *)(stream->buf))[4 * i + 3];
+                       if (!skip_x)
+                               ((TYPE *)(stream->buf))[4 * i + 0] *= a;
+                       if (!skip_y)
+                               ((TYPE *)(stream->buf))[4 * i + 1] *= a;
+                       if (!skip_z)
+                               ((TYPE *)(stream->buf))[4 * i + 2] *= a;
+               }
+               n *= stream->pixel_size;
+               ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");
+               memmove(stream->buf, stream->buf + n, stream->ptr -= n);
+       } while (eread_stream(stream, SIZE_MAX));
+       if (stream->ptr)
+               eprintf("%s: incomplete frame\n", stream->file);
+}
+
+#endif
diff --git a/src/blind-quaternion-product.c b/src/blind-quaternion-product.c
index 02bed9d..72744da 100644
--- a/src/blind-quaternion-product.c
+++ b/src/blind-quaternion-product.c
@@ -1,32 +1,11 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("right-hand-stream")
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *left, struct stream *right, size_t n)\
-       {\
-               size_t i;\
-               TYPE *lx, *ly, *lz, *la, *rx, *ry, *rz, *ra, x, y, z, a;\
-               for (i = 0; i < n; i += 4 * sizeof(TYPE)) {\
-                       lx = ((TYPE *)(left->buf + i)) + 0, rx = ((TYPE 
*)(right->buf + i)) + 0;\
-                       ly = ((TYPE *)(left->buf + i)) + 1, ry = ((TYPE 
*)(right->buf + i)) + 1;\
-                       lz = ((TYPE *)(left->buf + i)) + 2, rz = ((TYPE 
*)(right->buf + i)) + 2;\
-                       la = ((TYPE *)(left->buf + i)) + 3, ra = ((TYPE 
*)(right->buf + i)) + 3;\
-                       x = *lx * *rx - *ly * *ry - *lz * *rz - *la * *ra;\
-                       y = *lz * *ra - *la * *rz + *lx * *ry + *ly * *rx;\
-                       z = *la * *ry - *ly * *rz + *lx * *rz + *lz * *rx;\
-                       a = *ly * *rz - *lz * *rz + *lx * *ra + *la * *rx;\
-                       *lx = x;\
-                       *ly = y;\
-                       *lz = z;\
-                       *la = a;\
-               }\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-quaternion-product.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -51,3 +30,28 @@ main(int argc, char *argv[])
        process_two_streams(&left, &right, STDOUT_FILENO, "<stdout>", process);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *left, struct stream *right, size_t n)
+{
+       size_t i;
+       TYPE *lx, *ly, *lz, *la, *rx, *ry, *rz, *ra, x, y, z, a;
+       for (i = 0; i < n; i += 4 * sizeof(TYPE)) {
+               lx = ((TYPE *)(left->buf + i)) + 0, rx = ((TYPE *)(right->buf + 
i)) + 0;
+               ly = ((TYPE *)(left->buf + i)) + 1, ry = ((TYPE *)(right->buf + 
i)) + 1;
+               lz = ((TYPE *)(left->buf + i)) + 2, rz = ((TYPE *)(right->buf + 
i)) + 2;
+               la = ((TYPE *)(left->buf + i)) + 3, ra = ((TYPE *)(right->buf + 
i)) + 3;
+               x = *lx * *rx - *ly * *ry - *lz * *rz - *la * *ra;
+               y = *lz * *ra - *la * *rz + *lx * *ry + *ly * *rx;
+               z = *la * *ry - *ly * *rz + *lx * *rz + *lz * *rx;
+               a = *ly * *rz - *lz * *rz + *lx * *ra + *la * *rx;
+               *lx = x;
+               *ly = y;
+               *lz = z;
+               *la = a;
+       }
+}
+
+#endif
diff --git a/src/blind-radial-gradient.c b/src/blind-radial-gradient.c
index ce20366..e3483d3 100644
--- a/src/blind-radial-gradient.c
+++ b/src/blind-radial-gradient.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("-w width -h height")
@@ -7,79 +8,8 @@ static size_t width = 0;
 static size_t height = 0;
 static int with_params;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream)\
-       {\
-               typedef TYPE pixel_t[4];\
-               pixel_t buf[BUFSIZ / sizeof(pixel_t)];\
-               TYPE *params, x1, y1, x2, y2, norm, rd = 1, pe = 2, re = 2, e = 
0.5;\
-               TYPE x, y, p, r, rx, ry;\
-               size_t ix, iy, ptr = 0;\
-               for (;;) {\
-                       while (stream->ptr < stream->frame_size) {\
-                               if (!eread_stream(stream, stream->frame_size - 
stream->ptr)) {\
-                                       ewriteall(STDOUT_FILENO, buf, ptr * 
sizeof(*buf), "<stdout>");\
-                                       return;\
-                               }\
-                       }\
-                       params = (TYPE *)stream->buf;\
-                       x1 = (params)[0];\
-                       y1 = (params)[1];\
-                       x2 = (params)[4];\
-                       y2 = (params)[5];\
-                       if (with_params) {\
-                               pe = (params)[8];\
-                               re = (params)[9];\
-                               rd = (params)[10];\
-                               e = 1 / sqrt(pe * re);\
-                       }\
-                       memmove(stream->buf, stream->buf + stream->frame_size,\
-                               stream->ptr -= stream->frame_size);\
-                       \
-                       x2 -= x1;\
-                       y2 -= y1;\
-                       norm = sqrt(x2 * x2 + y2 * y2);\
-                       \
-                       if (!with_params) {\
-                               for (iy = 0; iy < height; iy++) {\
-                                       y = (TYPE)iy - y1;\
-                                       y *= y;\
-                                       for (ix = 0; ix < width; ix++) {\
-                                               x = (TYPE)ix - x1;\
-                                               x = sqrt(x * x + y) / norm;\
-                                               buf[ptr][0] = buf[ptr][1] = 
buf[ptr][2] = buf[ptr][3] = x;\
-                                               if (++ptr == ELEMENTSOF(buf)) {\
-                                                       
ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>");\
-                                                       ptr = 0;\
-                                               }\
-                                       }\
-                               }\
-                       } else {\
-                               for (iy = 0; iy < height; iy++) {\
-                                       y = (TYPE)iy - y1;\
-                                       for (ix = 0; ix < width; ix++) {\
-                                               x = (TYPE)ix - x1;\
-                                               p = (x * x2 + y * y2) / norm;\
-                                               rx = x - p * x2 / norm;\
-                                               ry = y - p * y2 / norm;\
-                                               r = sqrt(rx * rx + ry * ry) / 
rd;\
-                                               p = pow(abs(p / norm), pe);\
-                                               r = pow(abs(r / norm), re);\
-                                               x = pow(p + r, e);\
-                                               buf[ptr][0] = buf[ptr][1] = 
buf[ptr][2] = buf[ptr][3] = x;\
-                                               if (++ptr == ELEMENTSOF(buf)) {\
-                                                       
ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>");\
-                                                       ptr = 0;\
-                                               }\
-                                       }\
-                               }\
-                       }\
-               }\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-radial-gradient.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -124,3 +54,77 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       typedef TYPE pixel_t[4];
+       pixel_t buf[BUFSIZ / sizeof(pixel_t)];
+       TYPE *params, x1, y1, x2, y2, norm, rd = 1, pe = 2, re = 2, e = 0.5;
+       TYPE x, y, p, r, rx, ry;
+       size_t ix, iy, ptr = 0;
+       for (;;) {
+               while (stream->ptr < stream->frame_size) {
+                       if (!eread_stream(stream, stream->frame_size - 
stream->ptr)) {
+                               ewriteall(STDOUT_FILENO, buf, ptr * 
sizeof(*buf), "<stdout>");
+                               return;
+                       }
+               }
+               params = (TYPE *)stream->buf;
+               x1 = (params)[0];
+               y1 = (params)[1];
+               x2 = (params)[4];
+               y2 = (params)[5];
+               if (with_params) {
+                       pe = (params)[8];
+                       re = (params)[9];
+                       rd = (params)[10];
+                       e = 1 / sqrt(pe * re);
+               }
+               memmove(stream->buf, stream->buf + stream->frame_size,
+                       stream->ptr -= stream->frame_size);
+
+               x2 -= x1;
+               y2 -= y1;
+               norm = sqrt(x2 * x2 + y2 * y2);
+
+               if (!with_params) {
+                       for (iy = 0; iy < height; iy++) {
+                               y = (TYPE)iy - y1;
+                               y *= y;
+                               for (ix = 0; ix < width; ix++) {
+                                       x = (TYPE)ix - x1;
+                                       x = sqrt(x * x + y) / norm;
+                                       buf[ptr][0] = buf[ptr][1] = buf[ptr][2] 
= buf[ptr][3] = x;
+                                       if (++ptr == ELEMENTSOF(buf)) {
+                                               ewriteall(STDOUT_FILENO, buf, 
sizeof(buf), "<stdout>");
+                                               ptr = 0;
+                                       }
+                               }
+                       }
+               } else {
+                       for (iy = 0; iy < height; iy++) {
+                               y = (TYPE)iy - y1;
+                               for (ix = 0; ix < width; ix++) {
+                                       x = (TYPE)ix - x1;
+                                       p = (x * x2 + y * y2) / norm;
+                                       rx = x - p * x2 / norm;
+                                       ry = y - p * y2 / norm;
+                                       r = sqrt(rx * rx + ry * ry) / rd;
+                                       p = pow(abs(p / norm), pe);
+                                       r = pow(abs(r / norm), re);
+                                       x = pow(p + r, e);
+                                       buf[ptr][0] = buf[ptr][1] = buf[ptr][2] 
= buf[ptr][3] = x;
+                                       if (++ptr == ELEMENTSOF(buf)) {
+                                               ewriteall(STDOUT_FILENO, buf, 
sizeof(buf), "<stdout>");
+                                               ptr = 0;
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+#endif
diff --git a/src/blind-round-wave.c b/src/blind-round-wave.c
index 5aa3026..ac13e2c 100644
--- a/src/blind-round-wave.c
+++ b/src/blind-round-wave.c
@@ -1,45 +1,13 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-e]")
 
 static int equal = 0;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream)\
-       {\
-               size_t i, j, n;\
-               TYPE v, *p;\
-               do {\
-                       if (equal) {\
-                               n = stream->ptr / stream->pixel_size;\
-                               for (i = 0; i < n; i++) {\
-                                       p = (TYPE *)(stream->buf) + i * 
stream->n_chan;\
-                                       v = posmod(*p + 1, (TYPE)4) - 1;\
-                                       v = v < 1 ? 1 - v * v / 2 : (v - 2) * 
(v - 2) / 2;\
-                                       for (j = 0; j < stream->n_chan; j++)\
-                                               p[j] = v;\
-                               }\
-                               n *= stream->pixel_size;\
-                       } else {\
-                               n = stream->ptr / stream->chan_size;\
-                               for (i = 0; i < n; i++) {\
-                                       p = (TYPE *)(stream->buf) + i;\
-                                       v = posmod(*p + 1, (TYPE)4) - 1;\
-                                       *p = v < 1 ? 1 - v * v / 2 : (v - 2) * 
(v - 2) / 2;\
-                               }\
-                               n *= stream->chan_size;\
-                       }\
-                       ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");\
-                       memmove(stream->buf, stream->buf + n, stream->ptr -= 
n);\
-               } while (eread_stream(stream, SIZE_MAX));\
-               if (stream->ptr)\
-                       eprintf("%s: incomplete frame\n", stream->file);\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-round-wave.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -72,3 +40,39 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       size_t i, j, n;
+       TYPE v, *p;
+       do {
+               if (equal) {
+                       n = stream->ptr / stream->pixel_size;
+                       for (i = 0; i < n; i++) {
+                               p = (TYPE *)(stream->buf) + i * stream->n_chan;
+                               v = posmod(*p + 1, (TYPE)4) - 1;
+                               v = v < 1 ? 1 - v * v / 2 : (v - 2) * (v - 2) / 
2;
+                               for (j = 0; j < stream->n_chan; j++)
+                                       p[j] = v;
+                       }
+                       n *= stream->pixel_size;
+               } else {
+                       n = stream->ptr / stream->chan_size;
+                       for (i = 0; i < n; i++) {
+                               p = (TYPE *)(stream->buf) + i;
+                               v = posmod(*p + 1, (TYPE)4) - 1;
+                               *p = v < 1 ? 1 - v * v / 2 : (v - 2) * (v - 2) 
/ 2;
+                       }
+                       n *= stream->chan_size;
+               }
+               ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");
+               memmove(stream->buf, stream->buf + n, stream->ptr -= n);
+       } while (eread_stream(stream, SIZE_MAX));
+       if (stream->ptr)
+               eprintf("%s: incomplete frame\n", stream->file);
+}
+
+#endif
diff --git a/src/blind-sawtooth-wave.c b/src/blind-sawtooth-wave.c
index d1eeec1..213d261 100644
--- a/src/blind-sawtooth-wave.c
+++ b/src/blind-sawtooth-wave.c
@@ -1,43 +1,13 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-e]")
 
 static int equal = 0;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream)\
-       {\
-               size_t i, j, n;\
-               TYPE v, *p;\
-               do {\
-                       if (equal) {\
-                               n = stream->ptr / stream->pixel_size;\
-                               for (i = 0; i < n; i++) {\
-                                       p = (TYPE *)(stream->buf) + i * 
stream->n_chan;\
-                                       v = posmod(*p, (TYPE)1);\
-                                       for (j = 0; j < stream->n_chan; j++)\
-                                               p[j] = v;\
-                               }\
-                               n *= stream->pixel_size;\
-                       } else {\
-                               n = stream->ptr / stream->chan_size;\
-                               for (i = 0; i < n; i++) {\
-                                       p = (TYPE *)(stream->buf) + i;\
-                                       *p = posmod(*p, (TYPE)1);\
-                               }\
-                               n *= stream->chan_size;\
-                       }\
-                       ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");\
-                       memmove(stream->buf, stream->buf + n, stream->ptr -= 
n);\
-               } while (eread_stream(stream, SIZE_MAX));\
-               if (stream->ptr)\
-                       eprintf("%s: incomplete frame\n", stream->file);\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-sawtooth-wave.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -70,3 +40,37 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       size_t i, j, n;
+       TYPE v, *p;
+       do {
+               if (equal) {
+                       n = stream->ptr / stream->pixel_size;
+                       for (i = 0; i < n; i++) {
+                               p = (TYPE *)(stream->buf) + i * stream->n_chan;
+                               v = posmod(*p, (TYPE)1);
+                               for (j = 0; j < stream->n_chan; j++)
+                                       p[j] = v;
+                       }
+                       n *= stream->pixel_size;
+               } else {
+                       n = stream->ptr / stream->chan_size;
+                       for (i = 0; i < n; i++) {
+                               p = (TYPE *)(stream->buf) + i;
+                               *p = posmod(*p, (TYPE)1);
+                       }
+                       n *= stream->chan_size;
+               }
+               ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");
+               memmove(stream->buf, stream->buf + n, stream->ptr -= n);
+       } while (eread_stream(stream, SIZE_MAX));
+       if (stream->ptr)
+               eprintf("%s: incomplete frame\n", stream->file);
+}
+
+#endif
diff --git a/src/blind-set-luma.c b/src/blind-set-luma.c
index 2b077ad..8a14327 100644
--- a/src/blind-set-luma.c
+++ b/src/blind-set-luma.c
@@ -1,86 +1,11 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("luma-stream")
 
-#define PROCESS(TYPE)\
-       do {\
-               size_t i;\
-               TYPE a, y;\
-               for (i = 0; i < n; i += colour->pixel_size) {\
-                       a = ((TYPE *)(luma->buf + i))[1];\
-                       a *= ((TYPE *)(luma->buf + i))[3];\
-                       y = ((TYPE *)(colour->buf + i))[1];\
-                       ((TYPE *)(colour->buf + i))[0] += y * a - y;\
-                       ((TYPE *)(colour->buf + i))[1]  = y * a;\
-                       ((TYPE *)(colour->buf + i))[2] += y * a - y;\
-                       /*
-                        * Note, this changes the luma only, not the saturation,
-                        * so the result may look a bit weird. To change both
-                        * you can use `blind-arithm mul`.
-                        * 
-                        * Explaination of algorithm:
-                        * 
-                        *   Y is the luma, but (X, Z) is not the chroma,
-                        *   but in CIELAB, L* is the luma and (a*, *b) is
-                        *   the chroma. Multiplying
-                        *   
-                        *      ⎛0 1   0⎞
-                        *      ⎜1 −1  0⎟
-                        *      ⎝0  1 −1⎠
-                        *   
-                        *   (X Y Z)' gives a colour model similar to
-                        *   CIE L*a*b*: a model where each parameter is
-                        *   a linear transformation of the corresponding
-                        *   parameter in CIE L*a*b*. The inverse of that
-                        *   matrix is
-                        *   
-                        *      ⎛1 1  0⎞
-                        *      ⎜1 0  0⎟
-                        *      ⎝0 0 −1⎠
-                        *   
-                        *   and
-                        *   
-                        *      ⎛1 1  0⎞⎛a 0 0⎞⎛0 1   0⎞   ⎛1 
a−1 0⎞
-                        *      ⎜1 0  0⎟⎜0 1 0⎟⎜1 −1  0⎟ = ⎜0  
a  0⎟.
-                        *      ⎝0 0 −1⎠⎝0 0 1⎠⎝0  1 −1⎠   ⎝0 
a−1 1⎠
-                        * 
-                        * Explanation of why changing only the luma looks 
weird:
-                        * 
-                        *   Consider when you are workings with colours,
-                        *   when you want to change the brightness of a
-                        *   colour, you multiply all parameters: red, green,
-                        *   and blue, with the same value (this is however
-                        *   only an approximation in most cases, since you
-                        *   are usually usally working with colours that
-                        *   have the sRGB transfer function applied to their
-                        *   parameters). This action is the same in all
-                        *   colour models and colour spaces that are a
-                        *   linear transformation of the sRGB colour spaces
-                        *   (sans transfer function); this is simply because
-                        *   of the properties of linear transformations.
-                        * 
-                        *   The reason you change brightness this way can
-                        *   be explained by how objects reflect colour.
-                        *   Objects can only reject colours that are present
-                        *   in the light source. A ideal white object will look
-                        *   pure red if the light sources is ideal red, and a
-                        *   a ideal blue object will pure black in the same
-                        *   light source. An object can also not reflect
-                        *   colours brighter than the source. When the 
brightness
-                        *   of a light source is changed, the intensity of all
-                        *   colours (by wavelength) it emits is multiplied by
-                        *   one value. Therefore, when changing the brightness
-                        *   it looks most natural when all primaries (red, 
green,
-                        *   and blue) are multiplied by one value, or all
-                        *   parameters of the used colour spaces is a linear
-                        *   transformation of sRGB, such as CIE XYZ.
-                        */\
-               }\
-       } while (0)
-
-static void process_xyza (struct stream *colour, struct stream *luma, size_t 
n) {PROCESS(double);}
-static void process_xyzaf(struct stream *colour, struct stream *luma, size_t 
n) {PROCESS(float);}
+#define FILE "blind-set-luma.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -94,9 +19,9 @@ main(int argc, char *argv[])
        eopen_stream(&luma, argv[0]);
 
        if (!strcmp(colour.pixfmt, "xyza"))
-               process = process_xyza;
+               process = process_lf;
        else if (!strcmp(colour.pixfmt, "xyza f"))
-               process = process_xyzaf;
+               process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
colour.pixfmt);
 
@@ -105,3 +30,84 @@ main(int argc, char *argv[])
        process_two_streams(&colour, &luma, STDOUT_FILENO, "<stdout>", process);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *colour, struct stream *luma, size_t n)
+{\
+       size_t i;
+       TYPE a, y;
+       for (i = 0; i < n; i += colour->pixel_size) {
+               a = ((TYPE *)(luma->buf + i))[1];
+               a *= ((TYPE *)(luma->buf + i))[3];
+               y = ((TYPE *)(colour->buf + i))[1];
+               ((TYPE *)(colour->buf + i))[0] += y * a - y;
+               ((TYPE *)(colour->buf + i))[1]  = y * a;
+               ((TYPE *)(colour->buf + i))[2] += y * a - y;
+               /*
+                * Note, this changes the luma only, not the saturation,
+                * so the result may look a bit weird. To change both
+                * you can use `blind-arithm mul`.
+                * 
+                * Explaination of algorithm:
+                * 
+                *   Y is the luma, but (X, Z) is not the chroma,
+                *   but in CIELAB, L* is the luma and (a*, *b) is
+                *   the chroma. Multiplying
+                *   
+                *      ⎛0 1   0⎞
+                *      ⎜1 −1  0⎟
+                *      ⎝0  1 −1⎠
+                *   
+                *   (X Y Z)' gives a colour model similar to
+                *   CIE L*a*b*: a model where each parameter is
+                *   a linear transformation of the corresponding
+                *   parameter in CIE L*a*b*. The inverse of that
+                *   matrix is
+                *   
+                *      ⎛1 1  0⎞
+                *      ⎜1 0  0⎟
+                *      ⎝0 0 −1⎠
+                *   
+                *   and
+                *   
+                *      ⎛1 1  0⎞⎛a 0 0⎞⎛0 1   0⎞   ⎛1 a−1 0⎞
+                *      ⎜1 0  0⎟⎜0 1 0⎟⎜1 −1  0⎟ = ⎜0  a  0⎟.
+                *      ⎝0 0 −1⎠⎝0 0 1⎠⎝0  1 −1⎠   ⎝0 a−1 
1⎠
+                * 
+                * Explanation of why changing only the luma looks weird:
+                * 
+                *   Consider when you are workings with colours,
+                *   when you want to change the brightness of a
+                *   colour, you multiply all parameters: red, green,
+                *   and blue, with the same value (this is however
+                *   only an approximation in most cases, since you
+                *   are usually usally working with colours that
+                *   have the sRGB transfer function applied to their
+                *   parameters). This action is the same in all
+                *   colour models and colour spaces that are a
+                *   linear transformation of the sRGB colour spaces
+                *   (sans transfer function); this is simply because
+                *   of the properties of linear transformations.
+                * 
+                *   The reason you change brightness this way can
+                *   be explained by how objects reflect colour.
+                *   Objects can only reject colours that are present
+                *   in the light source. A ideal white object will look
+                *   pure red if the light sources is ideal red, and a
+                *   a ideal blue object will pure black in the same
+                *   light source. An object can also not reflect
+                *   colours brighter than the source. When the brightness
+                *   of a light source is changed, the intensity of all
+                *   colours (by wavelength) it emits is multiplied by
+                *   one value. Therefore, when changing the brightness
+                *   it looks most natural when all primaries (red, green,
+                *   and blue) are multiplied by one value, or all
+                *   parameters of the used colour spaces is a linear
+                *   transformation of sRGB, such as CIE XYZ.
+                */
+       }
+}
+
+#endif
diff --git a/src/blind-sinc-wave.c b/src/blind-sinc-wave.c
index f809c8e..ed36ce8 100644
--- a/src/blind-sinc-wave.c
+++ b/src/blind-sinc-wave.c
@@ -1,73 +1,13 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-e] [theta0-stream]")
 
 static int equal = 0;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *grad, struct stream *theta0)\
-       {\
-               size_t i, n, m = 0;\
-               TYPE *theta0xyza;\
-               TYPE x, theta0x = 0;\
-               TYPE y, theta0y = 0;\
-               TYPE z, theta0z = 0;\
-               TYPE a, theta0a = 0;\
-               do {\
-                       if (!m) {\
-                               m = grad->frame_size;\
-                               if (theta0) {\
-                                       while (theta0->ptr < 
theta0->frame_size)\
-                                               if (!eread_stream(theta0, 
theta0->frame_size - theta0->ptr))\
-                                                       return;\
-                                       theta0xyza = (TYPE *)theta0->buf;\
-                                       theta0x = (theta0xyza)[0];\
-                                       theta0y = (theta0xyza)[1];\
-                                       theta0z = (theta0xyza)[2];\
-                                       theta0a = (theta0xyza)[3];\
-                                       memmove(theta0->buf, theta0->buf + 
theta0->frame_size,\
-                                               theta0->ptr -= 
theta0->frame_size);\
-                               }\
-                       }\
-                       n = MIN(grad->ptr, m) / grad->pixel_size;\
-                       if (equal) {\
-                               for (i = 0; i < n; i++) {\
-                                       a = ((TYPE *)(grad->buf))[4 * i + 3];\
-                                       a = (a ? sin(a + theta0y) / a : sin(a + 
theta0y)) / 2 + (TYPE)0.5;\
-                                       ((TYPE *)(grad->buf))[4 * i + 0] = a;\
-                                       ((TYPE *)(grad->buf))[4 * i + 1] = a;\
-                                       ((TYPE *)(grad->buf))[4 * i + 2] = a;\
-                                       ((TYPE *)(grad->buf))[4 * i + 3] = a;\
-                               }\
-                       } else {\
-                               for (i = 0; i < n; i++) {\
-                                       x = ((TYPE *)(grad->buf))[4 * i + 0];\
-                                       y = ((TYPE *)(grad->buf))[4 * i + 1];\
-                                       z = ((TYPE *)(grad->buf))[4 * i + 2];\
-                                       a = ((TYPE *)(grad->buf))[4 * i + 3];\
-                                       x = (x ? sin(x + theta0x) / x : sin(x + 
theta0x)) / 2 + (TYPE)0.5;\
-                                       y = (y ? sin(y + theta0y) / y : sin(y + 
theta0y)) / 2 + (TYPE)0.5;\
-                                       z = (z ? sin(z + theta0z) / z : sin(z + 
theta0z)) / 2 + (TYPE)0.5;\
-                                       a = (a ? sin(a + theta0a) / a : sin(a + 
theta0a)) / 2 + (TYPE)0.5;\
-                                       ((TYPE *)(grad->buf))[4 * i + 0] = x;\
-                                       ((TYPE *)(grad->buf))[4 * i + 1] = y;\
-                                       ((TYPE *)(grad->buf))[4 * i + 2] = z;\
-                                       ((TYPE *)(grad->buf))[4 * i + 3] = a;\
-                               }\
-                       }\
-                       n *= grad->pixel_size;\
-                       m -= n;\
-                       ewriteall(STDOUT_FILENO, grad->buf, n, "<stdout>");\
-                       memmove(grad->buf, grad->buf + n, grad->ptr -= n);\
-               } while (eread_stream(grad, SIZE_MAX));\
-               if (grad->ptr)\
-                       eprintf("%s: incomplete frame\n", grad->file);\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-sinc-wave.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -111,3 +51,67 @@ main(int argc, char *argv[])
        process(&stream, have_theta0 ? &theta0 : NULL);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *grad, struct stream *theta0)
+{
+       size_t i, n, m = 0;
+       TYPE *theta0xyza;
+       TYPE x, theta0x = 0;
+       TYPE y, theta0y = 0;
+       TYPE z, theta0z = 0;
+       TYPE a, theta0a = 0;
+       do {
+               if (!m) {
+                       m = grad->frame_size;
+                       if (theta0) {
+                               while (theta0->ptr < theta0->frame_size)
+                                       if (!eread_stream(theta0, 
theta0->frame_size - theta0->ptr))
+                                               return;
+                               theta0xyza = (TYPE *)theta0->buf;
+                               theta0x = (theta0xyza)[0];
+                               theta0y = (theta0xyza)[1];
+                               theta0z = (theta0xyza)[2];
+                               theta0a = (theta0xyza)[3];
+                               memmove(theta0->buf, theta0->buf + 
theta0->frame_size,
+                                       theta0->ptr -= theta0->frame_size);
+                       }
+               }
+               n = MIN(grad->ptr, m) / grad->pixel_size;
+               if (equal) {
+                       for (i = 0; i < n; i++) {
+                               a = ((TYPE *)(grad->buf))[4 * i + 3];
+                               a = (a ? sin(a + theta0y) / a : sin(a + 
theta0y)) / 2 + (TYPE)0.5;
+                               ((TYPE *)(grad->buf))[4 * i + 0] = a;
+                               ((TYPE *)(grad->buf))[4 * i + 1] = a;
+                               ((TYPE *)(grad->buf))[4 * i + 2] = a;
+                               ((TYPE *)(grad->buf))[4 * i + 3] = a;
+                       }
+               } else {
+                       for (i = 0; i < n; i++) {
+                               x = ((TYPE *)(grad->buf))[4 * i + 0];
+                               y = ((TYPE *)(grad->buf))[4 * i + 1];
+                               z = ((TYPE *)(grad->buf))[4 * i + 2];
+                               a = ((TYPE *)(grad->buf))[4 * i + 3];
+                               x = (x ? sin(x + theta0x) / x : sin(x + 
theta0x)) / 2 + (TYPE)0.5;
+                               y = (y ? sin(y + theta0y) / y : sin(y + 
theta0y)) / 2 + (TYPE)0.5;
+                               z = (z ? sin(z + theta0z) / z : sin(z + 
theta0z)) / 2 + (TYPE)0.5;
+                               a = (a ? sin(a + theta0a) / a : sin(a + 
theta0a)) / 2 + (TYPE)0.5;
+                               ((TYPE *)(grad->buf))[4 * i + 0] = x;
+                               ((TYPE *)(grad->buf))[4 * i + 1] = y;
+                               ((TYPE *)(grad->buf))[4 * i + 2] = z;
+                               ((TYPE *)(grad->buf))[4 * i + 3] = a;
+                       }
+               }
+               n *= grad->pixel_size;
+               m -= n;
+               ewriteall(STDOUT_FILENO, grad->buf, n, "<stdout>");
+               memmove(grad->buf, grad->buf + n, grad->ptr -= n);
+       } while (eread_stream(grad, SIZE_MAX));
+       if (grad->ptr)
+               eprintf("%s: incomplete frame\n", grad->file);
+}
+
+#endif
diff --git a/src/blind-sine-wave.c b/src/blind-sine-wave.c
index 85bba2b..82c7794 100644
--- a/src/blind-sine-wave.c
+++ b/src/blind-sine-wave.c
@@ -1,47 +1,13 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-e]")
 
 static int equal = 0;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream)\
-       {\
-               size_t i, j, n;\
-               TYPE v, *p;\
-               do {\
-                       if (equal) {\
-                               n = stream->ptr / stream->pixel_size;\
-                               for (i = 0; i < n; i++) {\
-                                       p = (TYPE *)(stream->buf) + i * 
stream->n_chan;\
-                                       v = posmod(*p, (TYPE)2);\
-                                       v = v > 1 ? 2 - v : v;\
-                                       v = 1 - (cos(v * (TYPE)M_PI) + 1) / 2;\
-                                       for (j = 0; j < stream->n_chan; j++)\
-                                               p[j] = v;\
-                               }\
-                               n *= stream->pixel_size;\
-                       } else {\
-                               n = stream->ptr / stream->chan_size;\
-                               for (i = 0; i < n; i++) {\
-                                       p = (TYPE *)(stream->buf) + i;\
-                                       v = posmod(*p, (TYPE)2);\
-                                       v = v > 1 ? 2 - v : v;\
-                                       *p = 1 - (cos(v * (TYPE)M_PI) + 1) / 2;\
-                               }\
-                               n *= stream->chan_size;\
-                       }\
-                       ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");\
-                       memmove(stream->buf, stream->buf + n, stream->ptr -= 
n);\
-               } while (eread_stream(stream, SIZE_MAX));\
-               if (stream->ptr)\
-                       eprintf("%s: incomplete frame\n", stream->file);\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-sine-wave.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -74,3 +40,41 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       size_t i, j, n;
+       TYPE v, *p;
+       do {
+               if (equal) {
+                       n = stream->ptr / stream->pixel_size;
+                       for (i = 0; i < n; i++) {
+                               p = (TYPE *)(stream->buf) + i * stream->n_chan;
+                               v = posmod(*p, (TYPE)2);
+                               v = v > 1 ? 2 - v : v;
+                               v = 1 - (cos(v * (TYPE)M_PI) + 1) / 2;
+                               for (j = 0; j < stream->n_chan; j++)
+                                       p[j] = v;
+                       }
+                       n *= stream->pixel_size;
+               } else {
+                       n = stream->ptr / stream->chan_size;
+                       for (i = 0; i < n; i++) {
+                               p = (TYPE *)(stream->buf) + i;
+                               v = posmod(*p, (TYPE)2);
+                               v = v > 1 ? 2 - v : v;
+                               *p = 1 - (cos(v * (TYPE)M_PI) + 1) / 2;
+                       }
+                       n *= stream->chan_size;
+               }
+               ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");
+               memmove(stream->buf, stream->buf + n, stream->ptr -= n);
+       } while (eread_stream(stream, SIZE_MAX));
+       if (stream->ptr)
+               eprintf("%s: incomplete frame\n", stream->file);
+}
+
+#endif
diff --git a/src/blind-single-colour.c b/src/blind-single-colour.c
index 9dd1df9..8017a25 100644
--- a/src/blind-single-colour.c
+++ b/src/blind-single-colour.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-f frames | -f 'inf'] [-F pixel-format] -w width -h height (X Y Z | Y) 
[alpha]")
@@ -7,29 +8,8 @@ static struct stream stream = { .width = 0, .height = 0, 
.frames = 1 };
 static double X, Y, Z, alpha = 1;
 static int inf = 0;
 
-#define PROCESS(TYPE)\
-       do {\
-               typedef TYPE pixel_t[4];\
-               pixel_t buf[BUFSIZ / 4];\
-               size_t x, y, n;\
-               ssize_t r;\
-               \
-               for (x = 0; x < ELEMENTSOF(buf); x++) {\
-                       buf[x][0] = (TYPE)X;\
-                       buf[x][1] = (TYPE)Y;\
-                       buf[x][2] = (TYPE)Z;\
-                       buf[x][3] = (TYPE)alpha;\
-               }\
-               while (inf || stream.frames--)\
-                       for (y = stream.height; y--;)\
-                               for (x = stream.width * sizeof(*buf); x;)\
-                                       for (x -= n = MIN(sizeof(buf), x); n; n 
-= (size_t)r)\
-                                               if ((r = write(STDOUT_FILENO, 
buf, n)) < 0)\
-                                                       eprintf("write 
<stdout>:");\
-       } while (0)
-
-static void process_xyza(void)  {PROCESS(double);}
-static void process_xyzaf(void) {PROCESS(float);}
+#define FILE "blind-single-colour.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -79,9 +59,9 @@ main(int argc, char *argv[])
 
        pixfmt = get_pixel_format(pixfmt, "xyza");
        if (!strcmp(pixfmt, "xyza"))
-               process = process_xyza;
+               process = process_lf;
        else if (!strcmp(pixfmt, "xyza f"))
-               process = process_xyzaf;
+               process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", pixfmt);
 
@@ -92,3 +72,28 @@ main(int argc, char *argv[])
        process();
        return 0;
 }
+
+#else
+
+static void
+PROCESS(void)
+{
+       typedef TYPE pixel_t[4];
+       pixel_t buf[BUFSIZ / 4];
+       size_t x, y, n;
+       ssize_t r;
+       for (x = 0; x < ELEMENTSOF(buf); x++) {
+               buf[x][0] = (TYPE)X;
+               buf[x][1] = (TYPE)Y;
+               buf[x][2] = (TYPE)Z;
+               buf[x][3] = (TYPE)alpha;
+       }
+       while (inf || stream.frames--)
+               for (y = stream.height; y--;)
+                       for (x = stream.width * sizeof(*buf); x;)
+                               for (x -= n = MIN(sizeof(buf), x); n; n -= 
(size_t)r)
+                                       if ((r = write(STDOUT_FILENO, buf, n)) 
< 0)
+                                               eprintf("write <stdout>:");
+}
+
+#endif
diff --git a/src/blind-spectrum.c b/src/blind-spectrum.c
index 261d47c..2086ffc 100644
--- a/src/blind-spectrum.c
+++ b/src/blind-spectrum.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-y] [-z depth] spectrum-stream")
@@ -6,121 +7,8 @@ USAGE("[-y] [-z depth] spectrum-stream")
 static int luma = 0;
 static size_t nz = 1;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream, struct stream *spectrum)\
-       {\
-               TYPE *table = emalloc2(nz, spectrum->frame_size);\
-               size_t i, n, m = 0;\
-               TYPE x, y, z, a, x1, y1, z1, a1, x2, y2, z2, a2, ix, iy, iz, 
wx, wy, wz;\
-               size_t s, t, nx, ny, nxy;\
-               nx = spectrum->width;\
-               ny = spectrum->height;\
-               nxy = nx * ny;\
-               if (luma)\
-                       ny = nxy * nz;\
-               do {\
-                       if (!m) {\
-                               m = stream->frame_size;\
-                               for (i = 0; i < nz; i++) {\
-                                       if (!eread_frame(spectrum, ((char 
*)table) + i * spectrum->frame_size)) {\
-                                               if (!i)\
-                                                       goto done;\
-                                               eprintf("%s: incomplete frame 
set\n", spectrum->file);\
-                                       }\
-                               }\
-                       }\
-                       n = MIN(stream->ptr, m) / stream->pixel_size;\
-                       for (i = 0; i < n; i++) {\
-                               if (luma) {\
-                                       iy = ((TYPE *)(stream->buf))[4 * i + 
1];\
-                                       iy = MIN(MAX(iy, (TYPE)0), (TYPE)1);\
-                                       iy *= (TYPE)(ny - 1);\
-                                       s = (size_t)iy;\
-                                       t = s + 1;\
-                                       t = t == ny ? ny - 1 : t;\
-                                       wy = mod(iy, (TYPE)1);\
-                                       x = table[4 * s + 0] * (1 - wy) + 
table[4 * t + 0] * wy;\
-                                       y = table[4 * s + 1] * (1 - wy) + 
table[4 * t + 1] * wy;\
-                                       z = table[4 * s + 2] * (1 - wy) + 
table[4 * t + 2] * wy;\
-                                       a = table[4 * s + 3] * (1 - wy) + 
table[4 * t + 3] * wy;\
-                               } else {\
-                                       ix = ((TYPE *)(stream->buf))[4 * i + 
0];\
-                                       iy = ((TYPE *)(stream->buf))[4 * i + 
1];\
-                                       iz = ((TYPE *)(stream->buf))[4 * i + 
2];\
-                                       ix = MIN(MAX(ix, (TYPE)0), (TYPE)1);\
-                                       iy = MIN(MAX(iy, (TYPE)0), (TYPE)1);\
-                                       iz = MIN(MAX(iz, (TYPE)0), (TYPE)1);\
-                                       ix *= (TYPE)(nx - 1);\
-                                       iy *= (TYPE)(ny - 1);\
-                                       iz *= (TYPE)(nz - 1);\
-                                       wx = mod(ix, (TYPE)1);\
-                                       wy = mod(iy, (TYPE)1);\
-                                       wz = mod(iz, (TYPE)1);\
-                                       s = (size_t)ix;\
-                                       t = s + 1;\
-                                       t = t == nx ? nx - 1 : t;\
-                                       s += (size_t)iy * nx;\
-                                       t += (size_t)iy * nx;\
-                                       s += (size_t)iz * nxy;\
-                                       t += (size_t)iz * nxy;\
-                                       x = table[4 * s + 0] * (1 - wx) + 
table[4 * t + 0] * wx;\
-                                       y = table[4 * s + 1] * (1 - wx) + 
table[4 * t + 1] * wx;\
-                                       z = table[4 * s + 2] * (1 - wx) + 
table[4 * t + 2] * wx;\
-                                       a = table[4 * s + 3] * (1 - wx) + 
table[4 * t + 3] * wx;\
-                                       if ((size_t)iy != ny - 1) {\
-                                               s += nx, t += nx;\
-                                               x2 = table[4 * s + 0] * (1 - 
wx) + table[4 * t + 0] * wx;\
-                                               y2 = table[4 * s + 1] * (1 - 
wx) + table[4 * t + 1] * wx;\
-                                               z2 = table[4 * s + 2] * (1 - 
wx) + table[4 * t + 2] * wx;\
-                                               a2 = table[4 * s + 3] * (1 - 
wx) + table[4 * t + 3] * wx;\
-                                               x = x * (1 - wy) + x2 * wy;\
-                                               y = y * (1 - wy) + y2 * wy;\
-                                               z = z * (1 - wy) + z2 * wy;\
-                                               a = a * (1 - wy) + a2 * wy;\
-                                               s -= nx, t -= nx;\
-                                       }\
-                                       if ((size_t)iz != nz - 1) {\
-                                               s += nxy, t += nxy;\
-                                               x1 = table[4 * s + 0] * (1 - 
wx) + table[4 * t + 0] * wx;\
-                                               y1 = table[4 * s + 1] * (1 - 
wx) + table[4 * t + 1] * wx;\
-                                               z1 = table[4 * s + 2] * (1 - 
wx) + table[4 * t + 2] * wx;\
-                                               a1 = table[4 * s + 3] * (1 - 
wx) + table[4 * t + 3] * wx;\
-                                               if ((size_t)iy != ny - 1) {\
-                                                       s += nx, t += nx;\
-                                                       x2 = table[4 * s + 0] * 
(1 - wx) + table[4 * t + 0] * wx;\
-                                                       y2 = table[4 * s + 1] * 
(1 - wx) + table[4 * t + 1] * wx;\
-                                                       z2 = table[4 * s + 2] * 
(1 - wx) + table[4 * t + 2] * wx;\
-                                                       a2 = table[4 * s + 3] * 
(1 - wx) + table[4 * t + 3] * wx;\
-                                                       x1 = x1 * (1 - wy) + x2 
* wy;\
-                                                       y1 = y1 * (1 - wy) + y2 
* wy;\
-                                                       z1 = z1 * (1 - wy) + z2 
* wy;\
-                                                       a1 = a1 * (1 - wy) + a2 
* wy;\
-                                               }\
-                                               x = x * (1 - wz) + x1 * wz;\
-                                               y = y * (1 - wz) + y1 * wz;\
-                                               z = z * (1 - wz) + z1 * wz;\
-                                               a = a * (1 - wz) + a1 * wz;\
-                                       }\
-                               }\
-                               ((TYPE *)(stream->buf))[4 * i + 0] = x;\
-                               ((TYPE *)(stream->buf))[4 * i + 1] = y;\
-                               ((TYPE *)(stream->buf))[4 * i + 2] = z;\
-                               ((TYPE *)(stream->buf))[4 * i + 3] *= a;\
-                       }\
-                       n *= stream->pixel_size;\
-                       m -= n;\
-                       ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");\
-                       memmove(stream->buf, stream->buf + n, stream->ptr -= 
n);\
-               } while (eread_stream(stream, SIZE_MAX));\
-               if (stream->ptr)\
-                       eprintf("%s: incomplete frame\n", stream->file);\
-       done:\
-               free(table);\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-spectrum.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -162,3 +50,119 @@ main(int argc, char *argv[])
        process(&stream, &spectrum);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream, struct stream *spectrum)
+{
+       TYPE *table = emalloc2(nz, spectrum->frame_size);
+       size_t i, n, m = 0;
+       TYPE x, y, z, a, x1, y1, z1, a1, x2, y2, z2, a2, ix, iy, iz, wx, wy, wz;
+       size_t s, t, nx, ny, nxy;
+       nx = spectrum->width;
+       ny = spectrum->height;
+       nxy = nx * ny;
+       if (luma)
+               ny = nxy * nz;
+       do {
+               if (!m) {
+                       m = stream->frame_size;
+                       for (i = 0; i < nz; i++) {
+                               if (!eread_frame(spectrum, ((char *)table) + i 
* spectrum->frame_size)) {
+                                       if (!i)
+                                               goto done;
+                                       eprintf("%s: incomplete frame set\n", 
spectrum->file);
+                               }
+                       }
+               }
+               n = MIN(stream->ptr, m) / stream->pixel_size;
+               for (i = 0; i < n; i++) {
+                       if (luma) {
+                               iy = ((TYPE *)(stream->buf))[4 * i + 1];
+                               iy = MIN(MAX(iy, (TYPE)0), (TYPE)1);
+                               iy *= (TYPE)(ny - 1);
+                               s = (size_t)iy;
+                               t = s + 1;
+                               t = t == ny ? ny - 1 : t;
+                               wy = mod(iy, (TYPE)1);
+                               x = table[4 * s + 0] * (1 - wy) + table[4 * t + 
0] * wy;
+                               y = table[4 * s + 1] * (1 - wy) + table[4 * t + 
1] * wy;
+                               z = table[4 * s + 2] * (1 - wy) + table[4 * t + 
2] * wy;
+                               a = table[4 * s + 3] * (1 - wy) + table[4 * t + 
3] * wy;
+                       } else {
+                               ix = ((TYPE *)(stream->buf))[4 * i + 0];
+                               iy = ((TYPE *)(stream->buf))[4 * i + 1];
+                               iz = ((TYPE *)(stream->buf))[4 * i + 2];
+                               ix = MIN(MAX(ix, (TYPE)0), (TYPE)1);
+                               iy = MIN(MAX(iy, (TYPE)0), (TYPE)1);
+                               iz = MIN(MAX(iz, (TYPE)0), (TYPE)1);
+                               ix *= (TYPE)(nx - 1);
+                               iy *= (TYPE)(ny - 1);
+                               iz *= (TYPE)(nz - 1);
+                               wx = mod(ix, (TYPE)1);
+                               wy = mod(iy, (TYPE)1);
+                               wz = mod(iz, (TYPE)1);
+                               s = (size_t)ix;
+                               t = s + 1;
+                               t = t == nx ? nx - 1 : t;
+                               s += (size_t)iy * nx;
+                               t += (size_t)iy * nx;
+                               s += (size_t)iz * nxy;
+                               t += (size_t)iz * nxy;
+                               x = table[4 * s + 0] * (1 - wx) + table[4 * t + 
0] * wx;
+                               y = table[4 * s + 1] * (1 - wx) + table[4 * t + 
1] * wx;
+                               z = table[4 * s + 2] * (1 - wx) + table[4 * t + 
2] * wx;
+                               a = table[4 * s + 3] * (1 - wx) + table[4 * t + 
3] * wx;
+                               if ((size_t)iy != ny - 1) {
+                                       s += nx, t += nx;
+                                       x2 = table[4 * s + 0] * (1 - wx) + 
table[4 * t + 0] * wx;
+                                       y2 = table[4 * s + 1] * (1 - wx) + 
table[4 * t + 1] * wx;
+                                       z2 = table[4 * s + 2] * (1 - wx) + 
table[4 * t + 2] * wx;
+                                       a2 = table[4 * s + 3] * (1 - wx) + 
table[4 * t + 3] * wx;
+                                       x = x * (1 - wy) + x2 * wy;
+                                       y = y * (1 - wy) + y2 * wy;
+                                       z = z * (1 - wy) + z2 * wy;
+                                       a = a * (1 - wy) + a2 * wy;
+                                       s -= nx, t -= nx;
+                               }
+                               if ((size_t)iz != nz - 1) {
+                                       s += nxy, t += nxy;
+                                       x1 = table[4 * s + 0] * (1 - wx) + 
table[4 * t + 0] * wx;
+                                       y1 = table[4 * s + 1] * (1 - wx) + 
table[4 * t + 1] * wx;
+                                       z1 = table[4 * s + 2] * (1 - wx) + 
table[4 * t + 2] * wx;
+                                       a1 = table[4 * s + 3] * (1 - wx) + 
table[4 * t + 3] * wx;
+                                       if ((size_t)iy != ny - 1) {
+                                               s += nx, t += nx;
+                                               x2 = table[4 * s + 0] * (1 - 
wx) + table[4 * t + 0] * wx;
+                                               y2 = table[4 * s + 1] * (1 - 
wx) + table[4 * t + 1] * wx;
+                                               z2 = table[4 * s + 2] * (1 - 
wx) + table[4 * t + 2] * wx;
+                                               a2 = table[4 * s + 3] * (1 - 
wx) + table[4 * t + 3] * wx;
+                                               x1 = x1 * (1 - wy) + x2 * wy;
+                                               y1 = y1 * (1 - wy) + y2 * wy;
+                                               z1 = z1 * (1 - wy) + z2 * wy;
+                                               a1 = a1 * (1 - wy) + a2 * wy;
+                                       }
+                                       x = x * (1 - wz) + x1 * wz;
+                                       y = y * (1 - wz) + y1 * wz;
+                                       z = z * (1 - wz) + z1 * wz;
+                                       a = a * (1 - wz) + a1 * wz;
+                               }
+                       }
+                       ((TYPE *)(stream->buf))[4 * i + 0] = x;
+                       ((TYPE *)(stream->buf))[4 * i + 1] = y;
+                       ((TYPE *)(stream->buf))[4 * i + 2] = z;
+                       ((TYPE *)(stream->buf))[4 * i + 3] *= a;
+               }
+               n *= stream->pixel_size;
+               m -= n;
+               ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");
+               memmove(stream->buf, stream->buf + n, stream->ptr -= n);
+       } while (eread_stream(stream, SIZE_MAX));
+       if (stream->ptr)
+               eprintf("%s: incomplete frame\n", stream->file);
+done:
+       free(table);
+}
+
+#endif
diff --git a/src/blind-spiral-gradient.c b/src/blind-spiral-gradient.c
index efb5655..3835bf2 100644
--- a/src/blind-spiral-gradient.c
+++ b/src/blind-spiral-gradient.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-s spirals | t] [-al] -w width -h height")
@@ -12,108 +13,8 @@ static size_t height = 0;
 static int with_params;
 static int with_vector;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream)\
-       {\
-               typedef TYPE pixel_t[4];\
-               pixel_t buf[BUFSIZ / sizeof(pixel_t)];\
-               TYPE *params, x1, y1, x2, y2, b, r, u, v;\
-               TYPE x, y, a = 0, e = 1, p = 1, k = 1, ep = 1;\
-               TYPE x3 = 1, y3 = 0, rd = 1, P, R, Rx, Ry, Pe = 2, Re = 2, PRe 
= 0.5;\
-               size_t ix, iy, ptr = 0;\
-               for (;;) {\
-                       while (stream->ptr < stream->frame_size) {\
-                               if (!eread_stream(stream, stream->frame_size - 
stream->ptr)) {\
-                                       ewriteall(STDOUT_FILENO, buf, ptr * 
sizeof(*buf), "<stdout>");\
-                                       return;\
-                               }\
-                       }\
-                       params = (TYPE *)stream->buf;\
-                       x1 = (params)[0];\
-                       y1 = (params)[1];\
-                       x2 = (params)[4];\
-                       y2 = (params)[5];\
-                       if (with_vector) {\
-                               x3 = (params)[8];\
-                               y3 = (params)[9];\
-                               Pe = (params)[12];\
-                               Re = (params)[13];\
-                               rd = (params)[14];\
-                               PRe = 1 / sqrt(Pe * Re);\
-                               b = sqrt(x3 * x3 + y3 * y3);\
-                               x3 /= b;\
-                               y3 /= b;\
-                       }\
-                       if (with_params) {\
-                               a = (params)[with_vector ? 16 : 8];\
-                               e = (params)[with_vector ? 17 : 9];\
-                               p = (params)[with_vector ? 18 : 10];\
-                               k = (params)[with_vector ? 19 : 11];\
-                               ep = 1 / (e * p);\
-                       }\
-                       memmove(stream->buf, stream->buf + stream->frame_size,\
-                               stream->ptr -= stream->frame_size);\
-                       \
-                       x2 -= x1;\
-                       y2 -= y1;\
-                       u = atan2(y2, x2);\
-                       b = sqrt(x2 * x2 + y2 * y2);\
-                       b *= (TYPE)spirals;\
-                       if (logarithmic)\
-                               b = log(b);\
-                       b /= pow(2 * (TYPE)M_PI, e);\
-                       \
-                       for (iy = 0; iy < height; iy++) {\
-                               y = (TYPE)iy - y1;\
-                               for (ix = 0; ix < width; ix++) {\
-                                       x = (TYPE)ix - x1;\
-                                       if (!x && !y) {\
-                                               v = 0;\
-                                       } else {\
-                                               v = atan2(y, x);\
-                                               if (anticlockwise)\
-                                                       v = -v;\
-                                               v -= u;\
-                                               v += 4 * (TYPE)M_PI;\
-                                               v = mod(v, 2 * (TYPE)M_PI);\
-                                       }\
-                                       if (!with_vector) {\
-                                               r = sqrt(x * x + y * y);\
-                                       } else {\
-                                               P = x * x3 + y * y3;\
-                                               Rx = x - P * x3;\
-                                               Ry = y - P * y3;\
-                                               R = sqrt(Rx * Rx + Ry * Ry) / 
rd;\
-                                               P = pow(abs(P), Pe);\
-                                               R = pow(abs(R), Re);\
-                                               r = pow(P + R, PRe);\
-                                       }\
-                                       r -= a;\
-                                       if (!logarithmic) {\
-                                               r = pow(r / b, ep);\
-                                               r = (r - v) / (2 * (TYPE)M_PI);\
-                                       } else if (r) {\
-                                               r = log(r / k);\
-                                               r = pow(r / b, ep);\
-                                               r = (r - v) / (2 * (TYPE)M_PI);\
-                                       }\
-                                       if (angle)\
-                                               r = (TYPE)(int)(r + 1) + v / (2 
* (TYPE)M_PI); \
-                                       else\
-                                               r = mod(r, 1 / (TYPE)spirals) * 
(TYPE)spirals + r - mod(r, (TYPE)1);\
-                                       buf[ptr][0] = buf[ptr][1] = buf[ptr][2] 
= buf[ptr][3] = r;\
-                                       if (++ptr == ELEMENTSOF(buf)) {\
-                                               ewriteall(STDOUT_FILENO, buf, 
sizeof(buf), "<stdout>");\
-                                               ptr = 0;\
-                                       }\
-                               }\
-                       }\
-               }\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-spiral-gradient.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -173,3 +74,106 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       typedef TYPE pixel_t[4];
+       pixel_t buf[BUFSIZ / sizeof(pixel_t)];
+       TYPE *params, x1, y1, x2, y2, b, r, u, v;
+       TYPE x, y, a = 0, e = 1, p = 1, k = 1, ep = 1;
+       TYPE x3 = 1, y3 = 0, rd = 1, P, R, Rx, Ry, Pe = 2, Re = 2, PRe = 0.5;
+       size_t ix, iy, ptr = 0;
+       for (;;) {
+               while (stream->ptr < stream->frame_size) {
+                       if (!eread_stream(stream, stream->frame_size - 
stream->ptr)) {
+                               ewriteall(STDOUT_FILENO, buf, ptr * 
sizeof(*buf), "<stdout>");
+                               return;
+                       }
+               }
+               params = (TYPE *)stream->buf;
+               x1 = (params)[0];
+               y1 = (params)[1];
+               x2 = (params)[4];
+               y2 = (params)[5];
+               if (with_vector) {
+                       x3 = (params)[8];
+                       y3 = (params)[9];
+                       Pe = (params)[12];
+                       Re = (params)[13];
+                       rd = (params)[14];
+                       PRe = 1 / sqrt(Pe * Re);
+                       b = sqrt(x3 * x3 + y3 * y3);
+                       x3 /= b;
+                       y3 /= b;
+               }
+               if (with_params) {
+                       a = (params)[with_vector ? 16 : 8];
+                       e = (params)[with_vector ? 17 : 9];
+                       p = (params)[with_vector ? 18 : 10];
+                       k = (params)[with_vector ? 19 : 11];
+                       ep = 1 / (e * p);
+               }
+               memmove(stream->buf, stream->buf + stream->frame_size,
+                       stream->ptr -= stream->frame_size);
+
+               x2 -= x1;
+               y2 -= y1;
+               u = atan2(y2, x2);
+               b = sqrt(x2 * x2 + y2 * y2);
+               b *= (TYPE)spirals;
+               if (logarithmic)
+                       b = log(b);
+               b /= pow(2 * (TYPE)M_PI, e);
+
+               for (iy = 0; iy < height; iy++) {
+                       y = (TYPE)iy - y1;
+                       for (ix = 0; ix < width; ix++) {
+                               x = (TYPE)ix - x1;
+                               if (!x && !y) {
+                                       v = 0;
+                               } else {
+                                       v = atan2(y, x);
+                                       if (anticlockwise)
+                                               v = -v;
+                                       v -= u;
+                                       v += 4 * (TYPE)M_PI;
+                                       v = mod(v, 2 * (TYPE)M_PI);
+                               }
+                               if (!with_vector) {
+                                       r = sqrt(x * x + y * y);
+                               } else {
+                                       P = x * x3 + y * y3;
+                                       Rx = x - P * x3;
+                                       Ry = y - P * y3;
+                                       R = sqrt(Rx * Rx + Ry * Ry) / rd;
+                                       P = pow(abs(P), Pe);
+                                       R = pow(abs(R), Re);
+                                       r = pow(P + R, PRe);
+                               }
+                               r -= a;
+                               if (!logarithmic) {
+                                       r = pow(r / b, ep);
+                                       r = (r - v) / (2 * (TYPE)M_PI);
+                               } else if (r) {
+                                       r = log(r / k);
+                                       r = pow(r / b, ep);
+                                       r = (r - v) / (2 * (TYPE)M_PI);
+                               }
+                               if (angle)
+                                       r = (TYPE)(int)(r + 1) + v / (2 * 
(TYPE)M_PI); 
+                               else
+                                       r = mod(r, 1 / (TYPE)spirals) * 
(TYPE)spirals + r - mod(r, (TYPE)1);
+                               buf[ptr][0] = buf[ptr][1] = buf[ptr][2] = 
buf[ptr][3] = r;
+                               if (++ptr == ELEMENTSOF(buf)) {
+                                       ewriteall(STDOUT_FILENO, buf, 
sizeof(buf), "<stdout>");
+                                       ptr = 0;
+                               }
+                       }
+               }
+       }
+}
+
+#endif
diff --git a/src/blind-square-gradient.c b/src/blind-square-gradient.c
index 25f4893..bdd92bc 100644
--- a/src/blind-square-gradient.c
+++ b/src/blind-square-gradient.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("-w width -h height")
@@ -7,60 +8,8 @@ static size_t width = 0;
 static size_t height = 0;
 static int with_multiplier;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream)\
-       {\
-               typedef TYPE pixel_t[4];\
-               pixel_t buf[BUFSIZ / sizeof(pixel_t)];\
-               TYPE *params, x1, y1, x2, y2, norm, rd = 1; \
-               TYPE x, y, p, r, rx, ry;\
-               size_t ix, iy, ptr = 0;\
-               for (;;) {\
-                       while (stream->ptr < stream->frame_size) {\
-                               if (!eread_stream(stream, stream->frame_size - 
stream->ptr)) {\
-                                       ewriteall(STDOUT_FILENO, buf, ptr * 
sizeof(*buf), "<stdout>");\
-                                       return;\
-                               }\
-                       }\
-                       params = (TYPE *)stream->buf;\
-                       x1 = (params)[0];\
-                       y1 = (params)[1];\
-                       x2 = (params)[4];\
-                       y2 = (params)[5];\
-                       if (with_multiplier)\
-                               rd = (params)[9];\
-                       memmove(stream->buf, stream->buf + stream->frame_size,\
-                               stream->ptr -= stream->frame_size);\
-                       \
-                       x2 -= x1;\
-                       y2 -= y1;\
-                       norm = sqrt(x2 * x2 + y2 * y2);\
-                       x2 /= norm;\
-                       y2 /= norm;\
-                       \
-                       for (iy = 0; iy < height; iy++) {\
-                               y = (TYPE)iy - y1;\
-                               for (ix = 0; ix < width; ix++) {\
-                                       x = (TYPE)ix - x1;\
-                                       p = x * x2 + y * y2;\
-                                       rx = x - p * x2;\
-                                       ry = y - p * y2;\
-                                       r = sqrt(rx * rx + ry * ry) / rd;\
-                                       p = abs(p);\
-                                       x = MAX(p, r) / norm;\
-                                       buf[ptr][0] = buf[ptr][1] = buf[ptr][2] 
= buf[ptr][3] = x;\
-                                       if (++ptr == ELEMENTSOF(buf)) {\
-                                               ewriteall(STDOUT_FILENO, buf, 
sizeof(buf), "<stdout>");\
-                                               ptr = 0;\
-                                       }\
-                               }\
-                       }\
-               }\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-square-gradient.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -105,3 +54,58 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       typedef TYPE pixel_t[4];
+       pixel_t buf[BUFSIZ / sizeof(pixel_t)];
+       TYPE *params, x1, y1, x2, y2, norm, rd = 1; 
+       TYPE x, y, p, r, rx, ry;
+       size_t ix, iy, ptr = 0;
+       for (;;) {
+               while (stream->ptr < stream->frame_size) {
+                       if (!eread_stream(stream, stream->frame_size - 
stream->ptr)) {
+                               ewriteall(STDOUT_FILENO, buf, ptr * 
sizeof(*buf), "<stdout>");
+                               return;
+                       }
+               }
+               params = (TYPE *)stream->buf;
+               x1 = (params)[0];
+               y1 = (params)[1];
+               x2 = (params)[4];
+               y2 = (params)[5];
+               if (with_multiplier)
+                       rd = (params)[9];
+               memmove(stream->buf, stream->buf + stream->frame_size,
+                       stream->ptr -= stream->frame_size);
+
+               x2 -= x1;
+               y2 -= y1;
+               norm = sqrt(x2 * x2 + y2 * y2);
+               x2 /= norm;
+               y2 /= norm;
+
+               for (iy = 0; iy < height; iy++) {
+                       y = (TYPE)iy - y1;
+                       for (ix = 0; ix < width; ix++) {
+                               x = (TYPE)ix - x1;
+                               p = x * x2 + y * y2;
+                               rx = x - p * x2;
+                               ry = y - p * y2;
+                               r = sqrt(rx * rx + ry * ry) / rd;
+                               p = abs(p);
+                               x = MAX(p, r) / norm;
+                               buf[ptr][0] = buf[ptr][1] = buf[ptr][2] = 
buf[ptr][3] = x;
+                               if (++ptr == ELEMENTSOF(buf)) {
+                                       ewriteall(STDOUT_FILENO, buf, 
sizeof(buf), "<stdout>");
+                                       ptr = 0;
+                               }
+                       }
+               }
+       }
+}
+
+#endif
diff --git a/src/blind-tee.c b/src/blind-tee.c
index 55b6ef4..c0f54c9 100644
--- a/src/blind-tee.c
+++ b/src/blind-tee.c
@@ -3,10 +3,6 @@
 
 USAGE("[file ...]")
 
-#if !defined(PIPE_BUF)
-# define PIPE_BUF BUFSIZ
-#endif
-
 int
 main(int argc, char *argv[])
 {
diff --git a/src/blind-time-blur.c b/src/blind-time-blur.c
index 6144013..76ef17b 100644
--- a/src/blind-time-blur.c
+++ b/src/blind-time-blur.c
@@ -1,52 +1,13 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("alpha-stream")
 
 static int first = 1;
 
-#define PROCESS(TYPE)\
-       do {\
-               typedef TYPE pixel_t[4];\
-               pixel_t *restrict clr = (pixel_t *)cbuf;\
-               pixel_t *restrict alf = (pixel_t *)abuf;\
-               pixel_t *img = (pixel_t *)output;\
-               size_t i, n = colour->frame_size / sizeof(pixel_t);\
-               TYPE a1, a2;\
-               \
-               if (first) {\
-                       memcpy(output, cbuf, colour->frame_size);\
-                       first = 0;\
-                       return;\
-               }\
-               \
-               for (i = 0; i < n; i++, clr++, alf++, img++) {\
-                       a1 = (*img)[3];\
-                       a2 = (*clr)[3] * (*alf)[1] * (*alf)[3];\
-                       a1 *= (1 - a2);\
-                       (*img)[0] = (*img)[0] * a1 + (*clr)[0] * a2;\
-                       (*img)[1] = (*img)[1] * a1 + (*clr)[1] * a2;\
-                       (*img)[2] = (*img)[2] * a1 + (*clr)[2] * a2;\
-                       (*img)[3] = a1 + a2;\
-               }\
-               \
-               (void) colour;\
-               (void) alpha;\
-       } while (0)
-
-static void
-process_lf(char *output, char *restrict cbuf, char *restrict abuf,
-          struct stream *colour, struct stream *alpha)
-{
-       PROCESS(double);
-}
-
-static void
-process_f(char *output, char *restrict cbuf, char *restrict abuf,
-         struct stream *colour, struct stream *alpha)
-{
-       PROCESS(float);
-}
+#define FILE "blind-time-blur.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -79,3 +40,39 @@ main(int argc, char *argv[])
        process_each_frame_two_streams(&colour, &alpha, STDOUT_FILENO, 
"<stdout>", process);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(char *output, char *restrict cbuf, char *restrict abuf,
+        struct stream *colour, struct stream *alpha)
+{
+       typedef TYPE pixel_t[4];
+       pixel_t *restrict clr = (pixel_t *)cbuf;
+       pixel_t *restrict alf = (pixel_t *)abuf;
+       pixel_t *img = (pixel_t *)output;
+       size_t i, n = colour->frame_size / sizeof(pixel_t);
+       TYPE a1, a2;
+
+       if (first) {
+               memcpy(output, cbuf, colour->frame_size);
+               first = 0;
+               return;
+       }
+
+       for (i = 0; i < n; i++, clr++, alf++, img++) {
+               a1 = (*img)[3];
+               a2 = (*clr)[3] * (*alf)[1] * (*alf)[3];
+               a1 *= (1 - a2);
+               (*img)[0] = (*img)[0] * a1 + (*clr)[0] * a2;
+               (*img)[1] = (*img)[1] * a1 + (*clr)[1] * a2;
+               (*img)[2] = (*img)[2] * a1 + (*clr)[2] * a2;
+               (*img)[3] = a1 + a2;
+       }
+
+       (void) colour;
+       (void) alpha;
+
+}
+
+#endif
diff --git a/src/blind-to-text.c b/src/blind-to-text.c
index 7cee676..ecae9f2 100644
--- a/src/blind-to-text.c
+++ b/src/blind-to-text.c
@@ -1,8 +1,6 @@
 /* See LICENSE file for copyright and license details. */
 #include "common.h"
 
-#include <string.h>
-
 USAGE("")
 
 #define PROCESS(TYPE, CAST, FMT)\
diff --git a/src/blind-to-video.c b/src/blind-to-video.c
index ab09bfe..1c9ef99 100644
--- a/src/blind-to-video.c
+++ b/src/blind-to-video.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-d] frame-rate ffmpeg-arguments ...")
@@ -6,55 +7,8 @@ USAGE("[-d] frame-rate ffmpeg-arguments ...")
 static int draft = 0;
 static int fd;
 
-#define PROCESS(TYPE)\
-       do {\
-               char *buf = stream->buf;\
-               TYPE *pixel, r, g, b;\
-               uint16_t *pixels, *end;\
-               uint16_t pixbuf[BUFSIZ / sizeof(uint16_t)];\
-               long int a, y, u, v;\
-               size_t ptr;\
-               pixels = pixbuf;\
-               end = pixbuf + ELEMENTSOF(pixbuf);\
-               if (draft) {\
-                       for (ptr = 0; ptr < n; ptr += 4 * sizeof(TYPE)) {\
-                               pixel = (TYPE *)(buf + ptr);\
-                               ciexyz_to_scaled_yuv(pixel[0], pixel[1], 
pixel[2], &r, &g, &b);\
-                               y = (long int)r +  16L * 256L;\
-                               u = (long int)g + 128L * 256L;\
-                               v = (long int)b + 128L * 256L;\
-                               *pixels++ = 0xFFFFU;\
-                               *pixels++ = htole((uint16_t)CLIP(0, y, 
0xFFFFL));\
-                               *pixels++ = htole((uint16_t)CLIP(0, u, 
0xFFFFL));\
-                               *pixels++ = htole((uint16_t)CLIP(0, v, 
0xFFFFL));\
-                               if (pixels == end)\
-                                       ewriteall(fd, pixels = pixbuf, 
sizeof(pixbuf), "<subprocess>");\
-                       }\
-               } else {\
-                       for (ptr = 0; ptr < n; ptr += 4 * sizeof(TYPE)) {\
-                               pixel = (TYPE *)(buf + ptr);\
-                               a = (long int)(pixel[3] * 0xFFFFL);\
-                               ciexyz_to_srgb(pixel[0], pixel[1], pixel[2], 
&r, &g, &b);\
-                               r = srgb_encode(r);\
-                               g = srgb_encode(g);\
-                               b = srgb_encode(b);\
-                               srgb_to_yuv(r, g, b, pixel + 0, pixel + 1, 
pixel + 2);\
-                               y = (long int)(pixel[0] * 0xFFFFL) +  16L * 
256L;\
-                               u = (long int)(pixel[1] * 0xFFFFL) + 128L * 
256L;\
-                               v = (long int)(pixel[2] * 0xFFFFL) + 128L * 
256L;\
-                               *pixels++ = htole((uint16_t)CLIP(0, a, 
0xFFFFL));\
-                               *pixels++ = htole((uint16_t)CLIP(0, y, 
0xFFFFL));\
-                               *pixels++ = htole((uint16_t)CLIP(0, u, 
0xFFFFL));\
-                               *pixels++ = htole((uint16_t)CLIP(0, v, 
0xFFFFL));\
-                               if (pixels == end)\
-                                       ewriteall(fd, pixels = pixbuf, 
sizeof(pixbuf), "<subprocess>");\
-                       }\
-               }\
-               ewriteall(fd, pixbuf, (size_t)(pixels - pixbuf) * 
sizeof(*pixels), "<subprocess>");\
-       } while (0)
-
-static void process_xyza (struct stream *stream, size_t n) {PROCESS(double);}
-static void process_xyzaf(struct stream *stream, size_t n) {PROCESS(float);}
+#define FILE "blind-to-video.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -94,9 +48,9 @@ main(int argc, char *argv[])
        sprintf(geometry, "%zux%zu", stream.width, stream.height);
 
        if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_xyza;
+               process = process_lf;
        else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_xyzaf;
+               process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
 
@@ -121,3 +75,55 @@ main(int argc, char *argv[])
        ewaitpid(pid, &status, 0);
        return !!status;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream, size_t n)
+{
+       char *buf = stream->buf;
+       TYPE *pixel, r, g, b;
+       uint16_t *pixels, *end;
+       uint16_t pixbuf[BUFSIZ / sizeof(uint16_t)];
+       long int a, y, u, v;
+       size_t ptr;
+       pixels = pixbuf;
+       end = pixbuf + ELEMENTSOF(pixbuf);
+       if (draft) {
+               for (ptr = 0; ptr < n; ptr += 4 * sizeof(TYPE)) {
+                       pixel = (TYPE *)(buf + ptr);
+                       ciexyz_to_scaled_yuv(pixel[0], pixel[1], pixel[2], &r, 
&g, &b);
+                       y = (long int)r +  16L * 256L;
+                       u = (long int)g + 128L * 256L;
+                       v = (long int)b + 128L * 256L;
+                       *pixels++ = 0xFFFFU;
+                       *pixels++ = htole((uint16_t)CLIP(0, y, 0xFFFFL));
+                       *pixels++ = htole((uint16_t)CLIP(0, u, 0xFFFFL));
+                       *pixels++ = htole((uint16_t)CLIP(0, v, 0xFFFFL));
+                       if (pixels == end)
+                               ewriteall(fd, pixels = pixbuf, sizeof(pixbuf), 
"<subprocess>");
+               }
+       } else {
+               for (ptr = 0; ptr < n; ptr += 4 * sizeof(TYPE)) {
+                       pixel = (TYPE *)(buf + ptr);
+                       a = (long int)(pixel[3] * 0xFFFFL);
+                       ciexyz_to_srgb(pixel[0], pixel[1], pixel[2], &r, &g, 
&b);
+                       r = srgb_encode(r);
+                       g = srgb_encode(g);
+                       b = srgb_encode(b);
+                       srgb_to_yuv(r, g, b, pixel + 0, pixel + 1, pixel + 2);
+                       y = (long int)(pixel[0] * 0xFFFFL) +  16L * 256L;
+                       u = (long int)(pixel[1] * 0xFFFFL) + 128L * 256L;
+                       v = (long int)(pixel[2] * 0xFFFFL) + 128L * 256L;
+                       *pixels++ = htole((uint16_t)CLIP(0, a, 0xFFFFL));
+                       *pixels++ = htole((uint16_t)CLIP(0, y, 0xFFFFL));
+                       *pixels++ = htole((uint16_t)CLIP(0, u, 0xFFFFL));
+                       *pixels++ = htole((uint16_t)CLIP(0, v, 0xFFFFL));
+                       if (pixels == end)
+                               ewriteall(fd, pixels = pixbuf, sizeof(pixbuf), 
"<subprocess>");
+               }
+       }
+       ewriteall(fd, pixbuf, (size_t)(pixels - pixbuf) * sizeof(*pixels), 
"<subprocess>");
+}
+
+#endif
diff --git a/src/blind-triangular-wave.c b/src/blind-triangular-wave.c
index 8e32d0f..b1baf53 100644
--- a/src/blind-triangular-wave.c
+++ b/src/blind-triangular-wave.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-es]")
@@ -6,46 +7,8 @@ USAGE("[-es]")
 static int equal = 0;
 static int spiral = 0;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream)\
-       {\
-               size_t i, j, n;\
-               TYPE v, *p;\
-               do {\
-                       if (equal) {\
-                               n = stream->ptr / stream->pixel_size;\
-                               for (i = 0; i < n; i++) {\
-                                       p = (TYPE *)(stream->buf) + i * 
stream->n_chan;\
-                                       v = posmod(*p, (TYPE)2);\
-                                       v = v > 1 ? 2 - v : v;\
-                                       if (spiral)\
-                                               v = (v > (TYPE)0.5 ? 1 - v : v) 
* 2;\
-                                       for (j = 0; j < stream->n_chan; j++)\
-                                               p[j] = v;\
-                               }\
-                               n *= stream->pixel_size;\
-                       } else {\
-                               n = stream->ptr / stream->chan_size;\
-                               for (i = 0; i < n; i++) {\
-                                       p = (TYPE *)(stream->buf) + i;\
-                                       v = posmod(*p, (TYPE)2);\
-                                       v = v > 1 ? 2 - v : v;\
-                                       if (spiral)\
-                                               v = (v > (TYPE)0.5 ? 1 - v : v) 
* 2;\
-                                       *p = v;\
-                               }\
-                               n *= stream->chan_size;\
-                       }\
-                       ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");\
-                       memmove(stream->buf, stream->buf + n, stream->ptr -= 
n);\
-               } while (eread_stream(stream, SIZE_MAX));\
-               if (stream->ptr)\
-                       eprintf("%s: incomplete frame\n", stream->file);\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-triangular-wave.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -81,3 +44,44 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       size_t i, j, n;
+       TYPE v, *p;
+       do {
+               if (equal) {
+                       n = stream->ptr / stream->pixel_size;
+                       for (i = 0; i < n; i++) {
+                               p = (TYPE *)(stream->buf) + i * stream->n_chan;
+                               v = posmod(*p, (TYPE)2);
+                               v = v > 1 ? 2 - v : v;
+                               if (spiral)
+                                       v = (v > (TYPE)0.5 ? 1 - v : v) * 2;
+                               for (j = 0; j < stream->n_chan; j++)
+                                       p[j] = v;
+                       }
+                       n *= stream->pixel_size;
+               } else {
+                       n = stream->ptr / stream->chan_size;
+                       for (i = 0; i < n; i++) {
+                               p = (TYPE *)(stream->buf) + i;
+                               v = posmod(*p, (TYPE)2);
+                               v = v > 1 ? 2 - v : v;
+                               if (spiral)
+                                       v = (v > (TYPE)0.5 ? 1 - v : v) * 2;
+                               *p = v;
+                       }
+                       n *= stream->chan_size;
+               }
+               ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");
+               memmove(stream->buf, stream->buf + n, stream->ptr -= n);
+       } while (eread_stream(stream, SIZE_MAX));
+       if (stream->ptr)
+               eprintf("%s: incomplete frame\n", stream->file);
+}
+
+#endif
diff --git a/src/blind-unpremultiply.c b/src/blind-unpremultiply.c
index 18cc7b6..7545af4 100644
--- a/src/blind-unpremultiply.c
+++ b/src/blind-unpremultiply.c
@@ -1,4 +1,5 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-xyz]")
@@ -7,35 +8,8 @@ static int skip_x = 0;
 static int skip_y = 0;
 static int skip_z = 0;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *stream)\
-       {\
-               size_t i, n;\
-               TYPE a;\
-               do {\
-                       n = stream->ptr / stream->pixel_size;\
-                       for (i = 0; i < n; i++) {\
-                               a = ((TYPE *)(stream->buf))[4 * i + 3];\
-                               if (!a)\
-                                       continue;\
-                               if (!skip_x)\
-                                       ((TYPE *)(stream->buf))[4 * i + 0] /= 
a;\
-                               if (!skip_y)\
-                                       ((TYPE *)(stream->buf))[4 * i + 1] /= 
a;\
-                               if (!skip_z)\
-                                       ((TYPE *)(stream->buf))[4 * i + 2] /= 
a;\
-                       }\
-                       n *= stream->pixel_size;\
-                       ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");\
-                       memmove(stream->buf, stream->buf + n, stream->ptr -= 
n);\
-               } while (eread_stream(stream, SIZE_MAX));\
-               if (stream->ptr)\
-                       eprintf("%s: incomplete frame\n", stream->file);\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-unpremultiply.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -74,3 +48,33 @@ main(int argc, char *argv[])
        process(&stream);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream)
+{
+       size_t i, n;
+       TYPE a;
+       do {
+               n = stream->ptr / stream->pixel_size;
+               for (i = 0; i < n; i++) {
+                       a = ((TYPE *)(stream->buf))[4 * i + 3];
+                       if (!a)
+                               continue;
+                       if (!skip_x)
+                               ((TYPE *)(stream->buf))[4 * i + 0] /= a;
+                       if (!skip_y)
+                               ((TYPE *)(stream->buf))[4 * i + 1] /= a;
+                       if (!skip_z)
+                               ((TYPE *)(stream->buf))[4 * i + 2] /= a;
+               }
+               n *= stream->pixel_size;
+               ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");
+               memmove(stream->buf, stream->buf + n, stream->ptr -= n);
+       } while (eread_stream(stream, SIZE_MAX));
+       if (stream->ptr)
+               eprintf("%s: incomplete frame\n", stream->file);
+}
+
+#endif
diff --git a/src/blind-vector-projection.c b/src/blind-vector-projection.c
index c30643e..ea63e3b 100644
--- a/src/blind-vector-projection.c
+++ b/src/blind-vector-projection.c
@@ -1,45 +1,13 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("[-r | -s] plane-stream")
 
 static int level = 1;
 
-#define PROCESS(TYPE, SUFFIX)\
-       static void\
-       process_##SUFFIX(struct stream *left, struct stream *right, size_t n)\
-       {\
-               size_t i;\
-               TYPE *lx, *ly, *lz, *la, rx, ry, rz, ra, x, y, z, a, norm;\
-               for (i = 0; i < n; i += 4 * sizeof(TYPE)) {\
-                       lx = ((TYPE *)(left->buf + i)) + 0, rx = ((TYPE 
*)(right->buf + i))[0];\
-                       ly = ((TYPE *)(left->buf + i)) + 1, ry = ((TYPE 
*)(right->buf + i))[1];\
-                       lz = ((TYPE *)(left->buf + i)) + 2, rz = ((TYPE 
*)(right->buf + i))[2];\
-                       la = ((TYPE *)(left->buf + i)) + 3, ra = ((TYPE 
*)(right->buf + i))[3];\
-                       norm = rx * rx + ry * ry + rz * rz + ra * ra;\
-                       norm = sqrt(norm);\
-                       x = y = z = a = *lx * rx + *ly * ry + *lz * rz + *la * 
ra;\
-                       if (level) {\
-                               x *= rx;\
-                               y *= ry;\
-                               z *= rz;\
-                               a *= rz;\
-                               if (level > 1) {\
-                                       x = *lx - x;\
-                                       y = *ly - y;\
-                                       z = *lz - z;\
-                                       a = *la - a;\
-                               }\
-                       }\
-                       *lx = x;\
-                       *ly = y;\
-                       *lz = z;\
-                       *la = a;\
-               }\
-       }
-
-PROCESS(double, lf)
-PROCESS(float, f)
+#define FILE "blind-vector-projection.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -80,3 +48,39 @@ main(int argc, char *argv[])
        process_two_streams(&left, &right, STDOUT_FILENO, "<stdout>", process);
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *left, struct stream *right, size_t n)
+{
+       size_t i;
+       TYPE *lx, *ly, *lz, *la, rx, ry, rz, ra, x, y, z, a, norm;
+       for (i = 0; i < n; i += 4 * sizeof(TYPE)) {
+               lx = ((TYPE *)(left->buf + i)) + 0, rx = ((TYPE *)(right->buf + 
i))[0];
+               ly = ((TYPE *)(left->buf + i)) + 1, ry = ((TYPE *)(right->buf + 
i))[1];
+               lz = ((TYPE *)(left->buf + i)) + 2, rz = ((TYPE *)(right->buf + 
i))[2];
+               la = ((TYPE *)(left->buf + i)) + 3, ra = ((TYPE *)(right->buf + 
i))[3];
+               norm = rx * rx + ry * ry + rz * rz + ra * ra;
+               norm = sqrt(norm);
+               x = y = z = a = *lx * rx + *ly * ry + *lz * rz + *la * ra;
+               if (level) {
+                       x *= rx;
+                       y *= ry;
+                       z *= rz;
+                       a *= rz;
+                       if (level > 1) {
+                               x = *lx - x;
+                               y = *ly - y;
+                               z = *lz - z;
+                               a = *la - a;
+                       }
+               }
+               *lx = x;
+               *ly = y;
+               *lz = z;
+               *la = a;
+       }
+}
+
+#endif
diff --git a/src/common.h b/src/common.h
index a32f1a3..6113edf 100644
--- a/src/common.h
+++ b/src/common.h
@@ -64,3 +64,7 @@
 #ifndef CMSG_LEN
 # define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
 #endif
+
+#if !defined(PIPE_BUF)
+# define PIPE_BUF BUFSIZ
+#endif
diff --git a/src/define-functions.h b/src/define-functions.h
new file mode 100644
index 0000000..4952fe0
--- /dev/null
+++ b/src/define-functions.h
@@ -0,0 +1,13 @@
+/* See LICENSE file for copyright and license details. */
+
+#define PROCESS process_lf
+#define TYPE double
+#include FILE
+#undef PROCESS
+#undef TYPE
+
+#define PROCESS process_f
+#define TYPE float
+#include FILE
+#undef PROCESS
+#undef TYPE

Reply via email to