commit d05d162cb81664f292834fa5d48d623d2b6147a7
Author:     Mattias Andrée <[email protected]>
AuthorDate: Sun Jul 16 15:29:43 2017 +0200
Commit:     Mattias Andrée <[email protected]>
CommitDate: Sun Jul 16 15:29:43 2017 +0200

    Misc code improvements
    
    Signed-off-by: Mattias Andrée <[email protected]>

diff --git a/src/blind-apply-palette.c b/src/blind-apply-palette.c
index 113f57b..ad5fb4b 100644
--- a/src/blind-apply-palette.c
+++ b/src/blind-apply-palette.c
@@ -34,12 +34,7 @@ main(int argc, char *argv[])
        eopen_stream(&stream, NULL);
        eopen_stream(&palette, argv[0]);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
+       SELECT_PROCESS_FUNCTION(&stream);
 
        if (strcmp(stream.pixfmt, palette.pixfmt))
                eprintf("videos use incompatible pixel formats\n");
diff --git a/src/blind-chroma-key.c b/src/blind-chroma-key.c
index f670317..e9e8bcb 100644
--- a/src/blind-chroma-key.c
+++ b/src/blind-chroma-key.c
@@ -18,13 +18,7 @@ main(int argc, char *argv[])
        eopen_stream(&stream, NULL);
        eopen_stream(&key, argv[0]);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&stream);
        if (strcmp(stream.pixfmt, key.pixfmt))
                eprintf("videos use incompatible pixel formats\n");
 
diff --git a/src/blind-cone-gradient.c b/src/blind-cone-gradient.c
index c42a7e7..764307f 100644
--- a/src/blind-cone-gradient.c
+++ b/src/blind-cone-gradient.c
@@ -41,12 +41,7 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
+       SELECT_PROCESS_FUNCTION(&stream);
 
        if (stream.width > 3 || stream.height > 3 ||
            stream.width * stream.height < 2 ||
@@ -72,7 +67,7 @@ PROCESS(struct stream *stream)
        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;
+       size_t i, ix, iy, ptr = 0;
 
        for (;;) {
                while (stream->ptr < stream->frame_size) {
@@ -116,7 +111,8 @@ PROCESS(struct stream *stream)
                                                        v = 2 - v;
                                        }
                                }
-                               buf[ptr][0] = buf[ptr][1] = buf[ptr][2] = 
buf[ptr][3] = v;
+                               for (i = 0; i < stream->n_chan; i++)
+                                       buf[ptr][i] = x;
                                if (++ptr == ELEMENTSOF(buf)) {
                                        ewriteall(STDOUT_FILENO, buf, 
sizeof(buf), "<stdout>");
                                        ptr = 0;
diff --git a/src/blind-coordinate-field.c b/src/blind-coordinate-field.c
index 884b513..d4cd390 100644
--- a/src/blind-coordinate-field.c
+++ b/src/blind-coordinate-field.c
@@ -44,18 +44,10 @@ main(int argc, char *argv[])
        if (inf)
                einf_check_fd(STDOUT_FILENO, "<stdout>");
 
-       pixfmt = get_pixel_format(pixfmt, "xyza");
-       if (!strcmp(pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", pixfmt);
-
-       strcpy(stream.pixfmt, pixfmt);
+       eset_pixel_format(&stream, pixfmt);
+       SELECT_PROCESS_FUNCTION(&stream);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
-
        process();
        return 0;
 }
diff --git a/src/blind-cross-product.c b/src/blind-cross-product.c
index 1c369ba..910b49b 100644
--- a/src/blind-cross-product.c
+++ b/src/blind-cross-product.c
@@ -18,13 +18,7 @@ main(int argc, char *argv[])
        eopen_stream(&left, NULL);
        eopen_stream(&right, argv[0]);
 
-       if (left.encoding == DOUBLE)
-               process = process_lf;
-       else if (left.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
left.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&left);
        fprint_stream_head(stdout, &left);
        efflush(stdout, "<stdout>");
        process_two_streams(&left, &right, STDOUT_FILENO, "<stdout>", process);
diff --git a/src/blind-dot-product.c b/src/blind-dot-product.c
index 1d7053d..0a9e94e 100644
--- a/src/blind-dot-product.c
+++ b/src/blind-dot-product.c
@@ -18,13 +18,7 @@ main(int argc, char *argv[])
        eopen_stream(&left, NULL);
        eopen_stream(&right, argv[0]);
 
-       if (left.encoding == DOUBLE)
-               process = process_lf;
-       else if (left.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
left.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&left);
        fprint_stream_head(stdout, &left);
        efflush(stdout, "<stdout>");
        process_two_streams(&left, &right, STDOUT_FILENO, "<stdout>", process);
diff --git a/src/blind-double-sine-wave.c b/src/blind-double-sine-wave.c
index 0b009f3..0b58959 100644
--- a/src/blind-double-sine-wave.c
+++ b/src/blind-double-sine-wave.c
@@ -28,13 +28,7 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&stream);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
        process(&stream);
diff --git a/src/blind-dual-key.c b/src/blind-dual-key.c
index 2394085..6fa3348 100644
--- a/src/blind-dual-key.c
+++ b/src/blind-dual-key.c
@@ -28,13 +28,7 @@ main(int argc, char *argv[])
        eopen_stream(&stream, NULL);
        eopen_stream(&dual, argv[6]);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&stream);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
        process_two_streams(&stream, &dual, STDOUT_FILENO, "<stdout>", process);
diff --git a/src/blind-extract-alpha.c b/src/blind-extract-alpha.c
index 6b94c19..49b3947 100644
--- a/src/blind-extract-alpha.c
+++ b/src/blind-extract-alpha.c
@@ -19,18 +19,11 @@ main(int argc, char *argv[])
        eopen_stream(&stream, NULL);
        fd = eopen(argv[0], O_WRONLY | O_CREAT | O_TRUNC, 0666);
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&stream);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
        if (dprint_stream_head(fd, &stream) < 0)
                eprintf("dprintf %s:", argv[0]);
-
        process(&stream, fd, argv[0]);
        return 0;
 }
diff --git a/src/blind-find-rectangle.c b/src/blind-find-rectangle.c
index a71e7e9..ac6e843 100644
--- a/src/blind-find-rectangle.c
+++ b/src/blind-find-rectangle.c
@@ -9,7 +9,6 @@ struct pair {
 };
 
 static struct stream stream;
-static double X, Y, Z, alpha = 1;
 static size_t min_width = 1;
 static size_t min_height = 1;
 static size_t min_area = 1;
@@ -76,6 +75,7 @@ main(int argc, char *argv[])
 {
        double colour_lf[4];
        float colour_f[4];
+       double X, Y, Z, alpha = 1;
 
        ARGBEGIN {
        case 'a':
@@ -117,14 +117,12 @@ main(int argc, char *argv[])
                colour_lf[2] = Z;
                colour_lf[3] = alpha;
                process(colour_lf);
-       } else if (stream.encoding == FLOAT) {
+       } else {
                colour_f[0] = (float)X;
                colour_f[1] = (float)Y;
                colour_f[2] = (float)Z;
                colour_f[3] = (float)alpha;
                process(colour_f);
-       } else {
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
        }
 
        fshut(stdout, "<stdout>");
diff --git a/src/blind-flip.c b/src/blind-flip.c
index 84cbbf3..b4f4a13 100644
--- a/src/blind-flip.c
+++ b/src/blind-flip.c
@@ -21,7 +21,7 @@ main(int argc, char *argv[])
        while (eread_frame(&stream, buf))
                for (ptr = stream.frame_size; ptr;)
                        ewriteall(STDOUT_FILENO, buf + (ptr -= stream.row_size),
-                                 stream.row_size, "<stdout>");
+                                 stream.row_size, "<stdout>");
        /* ewriteall is faster than writev(3) and vmsplice(3) */
 
        free(buf);
diff --git a/src/blind-from-named.c b/src/blind-from-named.c
index 3b54884..b1fc3b8 100644
--- a/src/blind-from-named.c
+++ b/src/blind-from-named.c
@@ -40,9 +40,6 @@ erecv_fd(int sock)
 }
 
 #if !defined(HAVE_SENDFILE)
-# if !defined(PIPE_BUF)
-#  define PIPE_BUF BUFSIZ
-# endif
 static ssize_t
 sendfile(int outfd, int infd, off_t *offset, size_t count)
 {
diff --git a/src/blind-from-portable.c b/src/blind-from-portable.c
index 6e24100..c51e2db 100644
--- a/src/blind-from-portable.c
+++ b/src/blind-from-portable.c
@@ -3,6 +3,8 @@
 
 USAGE("[-s]")
 
+static int strict = 1;
+
 #define CONV(ITYPE, SITYPE, OTYPE, EXPONENT, HA2EXPONENT, FRACTION)\
        do {\
                static int cache_i = 0;\
@@ -74,15 +76,14 @@ USAGE("[-s]")
 static double conv_double(uint64_t portable) {CONV(uint64_t, int64_t, double, 
11, 1023, 52);}
 static float  conv_float (uint32_t portable) {CONV(uint32_t, int32_t, float,   
8,  127, 23);}
 
-static void process_lf(struct stream *stream, int strict) {PROCESS(uint64_t, 
double, 64);}
-static void process_f (struct stream *stream, int strict) {PROCESS(uint32_t, 
float,  32);}
+static void process_lf(struct stream *stream) {PROCESS(uint64_t, double, 64);}
+static void process_f (struct stream *stream) {PROCESS(uint32_t, float,  32);}
 
 int
 main(int argc, char *argv[])
 {
        struct stream stream;
-       int strict = 1;
-       void (*process)(struct stream *stream, int strict);
+       void (*process)(struct stream *stream);
 
        ARGBEGIN {
        case 's':
@@ -91,20 +92,16 @@ main(int argc, char *argv[])
        default:
                usage();
        } ARGEND;
+
        if (argc)
                usage();
 
        eopen_stream(&stream, NULL);
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported\n", stream.pixfmt);
+       SELECT_PROCESS_FUNCTION(&stream);
 
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
-       process(&stream, strict);
+       process(&stream);
        return 0;
 }
diff --git a/src/blind-from-text.c b/src/blind-from-text.c
index 4bf41f7..2832a9a 100644
--- a/src/blind-from-text.c
+++ b/src/blind-from-text.c
@@ -1,27 +1,11 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("")
 
-#define PROCESS(TYPE, FMT)\
-       do {\
-               TYPE buf[BUFSIZ / sizeof(TYPE)];\
-               size_t i;\
-               int r, done = 0;\
-               while (!done) {\
-                       for (i = 0; i < ELEMENTSOF(buf); i += (size_t)r) {\
-                               r = scanf("%"FMT, buf + i);\
-                               if (r == EOF) {\
-                                       done = 1;\
-                                       break;\
-                               }\
-                       }\
-                       ewriteall(STDOUT_FILENO, buf, i * sizeof(*buf), 
"<stdout>");\
-               }\
-       } while (0)
-
-static void process_lf(void) { PROCESS(double, "lf"); }
-static void process_f(void)  { PROCESS(float,  "f");  }
+#define FILE "blind-from-text.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -54,15 +38,31 @@ main(int argc, char *argv[])
        ewriteall(STDOUT_FILENO, stream.buf, stream.ptr, "<stdout>");
        einit_stream(&stream);
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&stream);
        process();
 
        efshut(stdin, "<stdin>");
        return 0;
 }
+
+#else
+
+static void
+PROCESS(void)
+{
+       TYPE buf[BUFSIZ / sizeof(TYPE)];
+       size_t i;
+       int r, done = 0;
+       while (!done) {
+               for (i = 0; i < ELEMENTSOF(buf); i += (size_t)r) {
+                       r = scanf("%"SCAN_TYPE, buf + i);
+                       if (r == EOF) {
+                               done = 1;
+                               break;
+                       }
+               }
+               ewriteall(STDOUT_FILENO, buf, i * sizeof(*buf), "<stdout>");
+       }
+}
+
+#endif
diff --git a/src/blind-gauss-blur.c b/src/blind-gauss-blur.c
index 3f4e08b..66583df 100644
--- a/src/blind-gauss-blur.c
+++ b/src/blind-gauss-blur.c
@@ -273,15 +273,15 @@ static size_t spread = 0;
        } while (0)
 
 static void
-process_xyza(char *restrict output, char *restrict cbuf, char *restrict sbuf,
-            struct stream *colour, struct stream *sigma)
+process_lf(char *restrict output, char *restrict cbuf, char *restrict sbuf,
+           struct stream *colour, struct stream *sigma)
 {
        PROCESS(double);
 }
 
 static void
-process_xyzaf(char *restrict output, char *restrict cbuf, char *restrict sbuf,
-            struct stream *colour, struct stream *sigma)
+process_f(char *restrict output, char *restrict cbuf, char *restrict sbuf,
+          struct stream *colour, struct stream *sigma)
 {
        PROCESS(float);
 }
@@ -292,7 +292,7 @@ main(int argc, char *argv[])
        struct stream colour, sigma;
        char *arg;
        void (*process)(char *restrict output, char *restrict cbuf, char 
*restrict sbuf,
-                       struct stream *colour, struct stream *sigma);
+                       struct stream *colour, struct stream *sigma);
 
        ARGBEGIN {
        case 'a':
@@ -333,12 +333,7 @@ main(int argc, char *argv[])
        eopen_stream(&colour, NULL);
        eopen_stream(&sigma, argv[0]);
 
-       if (!strcmp(colour.pixfmt, "xyza"))
-               process = process_xyza;
-       else if (!strcmp(colour.pixfmt, "xyza f"))
-               process = process_xyzaf;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
colour.pixfmt);
+       SELECT_PROCESS_FUNCTION(&colour);
 
        echeck_compat(&colour, &sigma);
 
@@ -348,6 +343,5 @@ main(int argc, char *argv[])
        fprint_stream_head(stdout, &colour);
        efflush(stdout, "<stdout>");
        process_each_frame_two_streams(&colour, &sigma, STDOUT_FILENO, 
"<stdout>", process);
-
        return 0;
 }
diff --git a/src/blind-get-colours.c b/src/blind-get-colours.c
index ba7c8ef..900ebce 100644
--- a/src/blind-get-colours.c
+++ b/src/blind-get-colours.c
@@ -63,11 +63,9 @@ main(int argc, char *argv[])
 
        do {
                n = stream.ptr / width;
-
                qsort(stream.buf, n, width, pixcmp);
                m = unique(stream.buf, n);
                ptr = merge(&colours, ptr, stream.buf, m, &siz);
-
                n *= width;
                memmove(stream.buf, stream.buf + n, stream.ptr -= n);
        } while (eread_stream(&stream, SIZE_MAX));
diff --git a/src/blind-hexagon-tessellation.c b/src/blind-hexagon-tessellation.c
index e282218..abb5c7a 100644
--- a/src/blind-hexagon-tessellation.c
+++ b/src/blind-hexagon-tessellation.c
@@ -4,8 +4,7 @@
 USAGE("[-F pixel-format] block-diameter")
 
 #define SET_XYZA(TYPE)\
-       (pixwidth *= sizeof(double),\
-        colours = alloca(4 * pixwidth),\
+       (colours = alloca(4 * stream.pixel_size),\
         ((TYPE *)colours)[ 0] = (TYPE)0.412457445582367600,\
         ((TYPE *)colours)[ 1] = (TYPE)0.212673370378408280,\
         ((TYPE *)colours)[ 2] = (TYPE)0.019333942761673460,\
@@ -30,7 +29,6 @@ main(int argc, char *argv[])
 {
        size_t diameter;
        const char *pixfmt = "xyza";
-       size_t pixwidth = 4;
        char *colours;
        size_t x, y, y2;
        int k;
@@ -48,15 +46,12 @@ main(int argc, char *argv[])
 
        diameter = etozu_arg("block-diameter", argv[0], 1, SIZE_MAX);
 
-       pixfmt = get_pixel_format(pixfmt, "xyza");
-       if (!strcmp(pixfmt, "xyza"))
+       eset_pixel_format(&stream, pixfmt);
+       if (stream.encoding == DOUBLE)
                SET_XYZA(double);
-       else if (!strcmp(pixfmt, "xyza f"))
-               SET_XYZA(float);
        else
-               eprintf("pixel format %s is not supported, try xyza\n", pixfmt);
+               SET_XYZA(float);
 
-       strcpy(stream.pixfmt, pixfmt);
        stream.width  = (size_t)((double)diameter * sqrt(3.));
        stream.height = diameter * 3 / 2;
        fprint_stream_head(stdout, &stream);
@@ -100,7 +95,7 @@ main(int argc, char *argv[])
                        } else {
                                k = (stream.width <= x * 4 && x * 4 < 
stream.width * 3) + 2;
                        }
-                       ewriteall(STDOUT_FILENO, colours + (size_t)k * 
pixwidth, pixwidth, "<stdout>");
+                       ewriteall(STDOUT_FILENO, colours + (size_t)k * 
stream.pixel_size, stream.pixel_size, "<stdout>");
                }
        }
 
diff --git a/src/blind-linear-gradient.c b/src/blind-linear-gradient.c
index 57cde3c..55711ac 100644
--- a/src/blind-linear-gradient.c
+++ b/src/blind-linear-gradient.c
@@ -36,12 +36,7 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
+       SELECT_PROCESS_FUNCTION(&stream);
 
        if (stream.width > 2 || stream.height > 2 || stream.width * 
stream.height != 2)
                eprintf("<stdin>: each frame must contain exactly 2 pixels\n");
@@ -63,7 +58,7 @@ PROCESS(struct stream *stream)
        pixel_t buf[BUFSIZ / sizeof(pixel_t)];
        TYPE *params, x1, y1, x2, y2, norm2;
        TYPE x, y;
-       size_t ix, iy, ptr = 0;
+       size_t i, ix, iy, ptr = 0;
 
        for (;;) {
                while (stream->ptr < stream->frame_size) {
@@ -91,7 +86,8 @@ PROCESS(struct stream *stream)
                                x = (x * x2 + y * y2) / norm2;
                                if (bilinear)
                                        x = abs(x);
-                               buf[ptr][0] = buf[ptr][1] = buf[ptr][2] = 
buf[ptr][3] = x;
+                               for (i = 0; i < stream->n_chan; i++)
+                                       buf[ptr][i] = x;
                                if (++ptr == ELEMENTSOF(buf)) {
                                        ewriteall(STDOUT_FILENO, buf, 
sizeof(buf), "<stdout>");
                                        ptr = 0;
diff --git a/src/blind-matrix-orthoproject.c b/src/blind-matrix-orthoproject.c
index 5bac543..816e76c 100644
--- a/src/blind-matrix-orthoproject.c
+++ b/src/blind-matrix-orthoproject.c
@@ -28,6 +28,8 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
+       SELECT_PROCESS_FUNCTION(&stream);
+
        if (stream.width > 2 || stream.height > 2 || stream.width * 
stream.height != 2)
                eprintf("<stdin>: each frame must contain exactly 2 pixels\n");
 
@@ -36,13 +38,6 @@ main(int argc, char *argv[])
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
        process(&stream);
        return 0;
 }
diff --git a/src/blind-matrix-reflect.c b/src/blind-matrix-reflect.c
index 45f6ed8..5dcf89e 100644
--- a/src/blind-matrix-reflect.c
+++ b/src/blind-matrix-reflect.c
@@ -28,6 +28,8 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
+       SELECT_PROCESS_FUNCTION(&stream);
+
        if (stream.width > 2 || stream.height > 2 || stream.width * 
stream.height != 2)
                eprintf("<stdin>: each frame must contain exactly 2 pixels\n");
 
@@ -36,13 +38,6 @@ main(int argc, char *argv[])
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
        process(&stream);
        return 0;
 }
diff --git a/src/blind-matrix-rotate.c b/src/blind-matrix-rotate.c
index f629df0..945205d 100644
--- a/src/blind-matrix-rotate.c
+++ b/src/blind-matrix-rotate.c
@@ -32,6 +32,8 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
+       SELECT_PROCESS_FUNCTION(&stream);
+
        if (stream.width != 1 || stream.height != 1)
                eprintf("<stdin>: each frame must contain exactly 1 pixels\n");
 
@@ -40,13 +42,6 @@ main(int argc, char *argv[])
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
        process(&stream);
        return 0;
 }
diff --git a/src/blind-matrix-scale.c b/src/blind-matrix-scale.c
index 9c5326f..15f27cc 100644
--- a/src/blind-matrix-scale.c
+++ b/src/blind-matrix-scale.c
@@ -28,6 +28,8 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
+       SELECT_PROCESS_FUNCTION(&stream);
+
        if (stream.width > 2 || stream.height > 2 || stream.width * 
stream.height != 2)
                eprintf("<stdin>: each frame must contain exactly 2 pixels\n");
 
@@ -36,13 +38,6 @@ main(int argc, char *argv[])
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
        process(&stream);
        return 0;
 }
diff --git a/src/blind-matrix-shear.c b/src/blind-matrix-shear.c
index d8ab02c..8130cba 100644
--- a/src/blind-matrix-shear.c
+++ b/src/blind-matrix-shear.c
@@ -36,6 +36,8 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
+       SELECT_PROCESS_FUNCTION(&stream);
+
        if (stream.width > 2 || stream.height > 2 || stream.width * 
stream.height != 2)
                eprintf("<stdin>: each frame must contain exactly 2 pixels\n");
 
@@ -44,13 +46,6 @@ main(int argc, char *argv[])
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
        process(&stream);
        return 0;
 }
diff --git a/src/blind-matrix-translate.c b/src/blind-matrix-translate.c
index beb84d9..5ae1104 100644
--- a/src/blind-matrix-translate.c
+++ b/src/blind-matrix-translate.c
@@ -28,6 +28,8 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
+       SELECT_PROCESS_FUNCTION(&stream);
+
        if (stream.width > 2 || stream.height > 2 || stream.width * 
stream.height != 2)
                eprintf("<stdin>: each frame must contain exactly 2 pixels\n");
 
@@ -36,13 +38,6 @@ main(int argc, char *argv[])
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
        process(&stream);
        return 0;
 }
diff --git a/src/blind-matrix-transpose.c b/src/blind-matrix-transpose.c
index 2634b8f..3f19053 100644
--- a/src/blind-matrix-transpose.c
+++ b/src/blind-matrix-transpose.c
@@ -28,6 +28,8 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
+       SELECT_PROCESS_FUNCTION(&stream);
+
        if (stream.width != 1 || stream.height != 1)
                eprintf("<stdin>: each frame must contain exactly 1 pixels\n");
 
@@ -36,13 +38,6 @@ main(int argc, char *argv[])
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
        process(&stream);
        return 0;
 }
diff --git a/src/blind-mosaic-edges.c b/src/blind-mosaic-edges.c
index 3b9ff55..b59dbda 100644
--- a/src/blind-mosaic-edges.c
+++ b/src/blind-mosaic-edges.c
@@ -10,9 +10,7 @@ main(int argc, char *argv[])
        int tiled_y = 0;
        struct stream stream;
        void *colours[2];
-       char *buf;
-       char *edges;
-       char *here;
+       char *buf, *edges, *here;
        size_t i, n, x, y;
        int v;
 
@@ -65,37 +63,37 @@ main(int argc, char *argv[])
                        x = i % stream.width;
                        y = i / stream.width;
 
-                       if (x != stream.width - 1 &&
-                           memcmp(here + stream.pixel_size, here, 
stream.pixel_size))
-                               goto at_edge;
-
-                       if (tiled_x && x == stream.width - 1 &&
-                           memcmp(here + stream.pixel_size - stream.row_size, 
here, stream.pixel_size))
-                               goto at_edge;
-
-                       if (x &&
-                           memcmp(here - stream.pixel_size, here, 
stream.pixel_size))
-                               goto at_edge;
-
-                       if (tiled_x && !x &&
-                           memcmp(here + stream.row_size - stream.pixel_size, 
here, stream.pixel_size))
-                               goto at_edge;
-
-                       if (y != stream.height - 1 &&
-                           memcmp(here + stream.row_size, here, 
stream.pixel_size))
-                               goto at_edge;
-
-                       if (tiled_y && y == stream.height - 1 &&
-                           memcmp(here + stream.row_size - stream.frame_size, 
here, stream.pixel_size))
-                               goto at_edge;
-
-                       if (y &&
-                           memcmp(here - stream.row_size, here, 
stream.pixel_size))
-                               goto at_edge;
-
-                       if (tiled_y && !y &&
-                           memcmp(here + stream.frame_size - stream.row_size, 
here, stream.pixel_size))
-                               goto at_edge;
+                       if (x != stream.width - 1) {
+                               if (memcmp(here + stream.pixel_size, here, 
stream.pixel_size))
+                                       goto at_edge;
+                       } else if (tiled_x) {
+                               if (memcmp(here + stream.pixel_size - 
stream.row_size, here, stream.pixel_size))
+                                       goto at_edge;
+                       }
+
+                       if (x) {
+                               if (memcmp(here - stream.pixel_size, here, 
stream.pixel_size))
+                                       goto at_edge;
+                       } else if (tiled_x) {
+                               if (memcmp(here + stream.row_size - 
stream.pixel_size, here, stream.pixel_size))
+                                       goto at_edge;
+                       }
+
+                       if (y != stream.height - 1) {
+                               if (memcmp(here + stream.row_size, here, 
stream.pixel_size))
+                                       goto at_edge;
+                       } else if (tiled_y) {
+                               if (memcmp(here + stream.row_size - 
stream.frame_size, here, stream.pixel_size))
+                                       goto at_edge;
+                       }
+
+                       if (y) {
+                               if (memcmp(here - stream.row_size, here, 
stream.pixel_size))
+                                       goto at_edge;
+                       } else if (tiled_y) {
+                               if (memcmp(here + stream.frame_size - 
stream.row_size, here, stream.pixel_size))
+                                       goto at_edge;
+                       }
 
                        continue;
                at_edge:
diff --git a/src/blind-mosaic.c b/src/blind-mosaic.c
index 08727e9..a0f36da 100644
--- a/src/blind-mosaic.c
+++ b/src/blind-mosaic.c
@@ -157,18 +157,11 @@ main(int argc, char *argv[])
        eopen_stream(&colour, NULL);
        eopen_stream(&mosaic, argv[0]);
 
-       if (!strcmp(colour.pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(colour.pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
colour.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&colour);
        echeck_compat(&colour, &mosaic);
 
        fprint_stream_head(stdout, &colour);
        efflush(stdout, "<stdout>");
        process_each_frame_two_streams(&colour, &mosaic, STDOUT_FILENO, 
"<stdout>", process);
-
        return 0;
 }
diff --git a/src/blind-multiply-matrices.c b/src/blind-multiply-matrices.c
index 6aea2f0..af86311 100644
--- a/src/blind-multiply-matrices.c
+++ b/src/blind-multiply-matrices.c
@@ -66,12 +66,7 @@ main(int argc, char *argv[])
                height = streams[i].height;
        }
 
-       if (streams->encoding == DOUBLE)
-               process = process_lf;
-       else if (streams->encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
streams->pixfmt);
+       SELECT_PROCESS_FUNCTION(streams);
 
        w = streams->width,  streams->width  = max_width;
        h = streams->height, streams->height = max_height;
diff --git a/src/blind-next-frame.c b/src/blind-next-frame.c
index 260c375..be6c303 100644
--- a/src/blind-next-frame.c
+++ b/src/blind-next-frame.c
@@ -6,13 +6,11 @@ USAGE("[-f frames] width height pixel-format ...")
 int
 main(int argc, char *argv[])
 {
-       struct stream stream;
+       struct stream stream = { .frames = 1, .fd = STDIN_FILENO, .file = 
"<stdin>" };
        size_t n;
        int i;
        char *p;
 
-       stream.frames = 1;
-
        ARGBEGIN {
        case 'f':
                stream.frames = entozu_flag(2, 'f', UARGF(), 1, SIZE_MAX);
@@ -24,10 +22,7 @@ main(int argc, char *argv[])
        if (argc < 3)
                usage();
 
-       stream.fd = STDIN_FILENO;
-       stream.file = "<stdin>";
        stream.pixfmt[0] = '\0';
-
        stream.width  = entozu_arg(2, "the width",  argv[0], 1, SIZE_MAX);
        stream.height = entozu_arg(2, "the height", argv[1], 1, SIZE_MAX);
        argv += 2, argc -= 2;
@@ -42,8 +37,7 @@ main(int argc, char *argv[])
                        p = stpcpy(p, argv[i]);
                }
        }
-
-       enset_pixel_size(2, &stream);
+       enset_pixel_format(2, &stream, NULL);
 
        fprint_stream_head(stdout, &stream);
        enfflush(2, stdout, "<stdout>");
diff --git a/src/blind-norm.c b/src/blind-norm.c
index 8a2b223..9458361 100644
--- a/src/blind-norm.c
+++ b/src/blind-norm.c
@@ -40,13 +40,7 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&stream);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
        process(&stream);
diff --git a/src/blind-premultiply.c b/src/blind-premultiply.c
index 5d46c06..c670b60 100644
--- a/src/blind-premultiply.c
+++ b/src/blind-premultiply.c
@@ -36,13 +36,7 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&stream);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
        process(&stream);
diff --git a/src/blind-quaternion-product.c b/src/blind-quaternion-product.c
index 72744da..06a2887 100644
--- a/src/blind-quaternion-product.c
+++ b/src/blind-quaternion-product.c
@@ -18,13 +18,7 @@ main(int argc, char *argv[])
        eopen_stream(&left, NULL);
        eopen_stream(&right, argv[0]);
 
-       if (left.encoding == DOUBLE)
-               process = process_lf;
-       else if (left.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
left.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&left);
        fprint_stream_head(stdout, &left);
        efflush(stdout, "<stdout>");
        process_two_streams(&left, &right, STDOUT_FILENO, "<stdout>", process);
diff --git a/src/blind-radial-gradient.c b/src/blind-radial-gradient.c
index e3483d3..a97e474 100644
--- a/src/blind-radial-gradient.c
+++ b/src/blind-radial-gradient.c
@@ -33,12 +33,7 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
+       SELECT_PROCESS_FUNCTION(&stream);
 
        if (stream.width > 3 || stream.height > 3 ||
            stream.width * stream.height < 2 ||
@@ -64,7 +59,7 @@ PROCESS(struct stream *stream)
        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;
+       size_t i, ix, iy, ptr = 0;
        for (;;) {
                while (stream->ptr < stream->frame_size) {
                        if (!eread_stream(stream, stream->frame_size - 
stream->ptr)) {
@@ -97,7 +92,8 @@ PROCESS(struct stream *stream)
                                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;
+                                       for (i = 0; i < stream->n_chan; i++)
+                                               buf[ptr][i] = x;
                                        if (++ptr == ELEMENTSOF(buf)) {
                                                ewriteall(STDOUT_FILENO, buf, 
sizeof(buf), "<stdout>");
                                                ptr = 0;
@@ -116,7 +112,8 @@ PROCESS(struct stream *stream)
                                        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;
+                                       for (i = 0; i < stream->n_chan; i++)
+                                               buf[ptr][i] = x;
                                        if (++ptr == ELEMENTSOF(buf)) {
                                                ewriteall(STDOUT_FILENO, buf, 
sizeof(buf), "<stdout>");
                                                ptr = 0;
diff --git a/src/blind-rectangle-tessellation.c 
b/src/blind-rectangle-tessellation.c
index a139934..2d83222 100644
--- a/src/blind-rectangle-tessellation.c
+++ b/src/blind-rectangle-tessellation.c
@@ -4,8 +4,7 @@
 USAGE("[-F pixel-format] block-width block-height")
 
 #define SET_XYZA(TYPE)\
-       (pixwidth *= sizeof(double),\
-        colours = alloca(4 * pixwidth),\
+       (colours = alloca(4 * stream.pixel_size),\
         ((TYPE *)colours)[ 0] = (TYPE)0.412457445582367600,\
         ((TYPE *)colours)[ 1] = (TYPE)0.212673370378408280,\
         ((TYPE *)colours)[ 2] = (TYPE)0.019333942761673460,\
@@ -30,7 +29,6 @@ main(int argc, char *argv[])
 {
        size_t width, height;
        const char *pixfmt = "xyza";
-       size_t pixwidth = 4;
        char *colours;
        size_t x1, y1, x2, y2;
 
@@ -48,15 +46,12 @@ main(int argc, char *argv[])
        width  = etozu_arg("block-width", argv[0], 1, SIZE_MAX);
        height = etozu_arg("block-height", argv[1], 1, SIZE_MAX);
 
-       pixfmt = get_pixel_format(pixfmt, "xyza");
-       if (!strcmp(pixfmt, "xyza"))
+       eset_pixel_format(&stream, pixfmt);
+       if (stream.encoding == DOUBLE)
                SET_XYZA(double);
-       else if (!strcmp(pixfmt, "xyza f"))
-               SET_XYZA(float);
        else
-               eprintf("pixel format %s is not supported, try xyza\n", pixfmt);
+               SET_XYZA(float);
 
-       strcpy(stream.pixfmt, pixfmt);
        stream.width  = 2 * width;
        stream.height = 2 * height;
        fprint_stream_head(stdout, &stream);
@@ -66,7 +61,8 @@ main(int argc, char *argv[])
                for (y2 = 0; y2 < height; y2++)
                        for (x1 = 0; x1 < 2; x1++)
                                for (x2 = 0; x2 < width; x2++)
-                                       ewriteall(STDOUT_FILENO, colours + (y1 
* 2 + x1) * pixwidth, pixwidth, "<stdout>");
+                                       ewriteall(STDOUT_FILENO, colours + (y1 
* 2 + x1) * stream.pixel_size,
+                                                 stream.pixel_size, 
"<stdout>");
 
        return 0;
 }
diff --git a/src/blind-reverse.c b/src/blind-reverse.c
index 0851f1f..b99bd33 100644
--- a/src/blind-reverse.c
+++ b/src/blind-reverse.c
@@ -98,9 +98,7 @@ main(int argc, char *argv[])
        if (stream.frames * stream.frame_size > (size_t)SSIZE_MAX - 
stream.headlen)
                eprintf("%s: video is too large\n", stream.file);
 
-#if defined(POSIX_FADV_RANDOM)
-       posix_fadvise(stream.fd, 0, 0, POSIX_FADV_RANDOM);
-#endif
+       fadvise_random(stream.fd, 0, 0);
 
        (inplace ? in_place : to_stdout)(&stream);
        close(stream.fd);
diff --git a/src/blind-rewrite-head.c b/src/blind-rewrite-head.c
index ca31006..aad19e4 100644
--- a/src/blind-rewrite-head.c
+++ b/src/blind-rewrite-head.c
@@ -65,7 +65,6 @@ main(int argc, char *argv[])
                usage();
        } ARGEND;
 
-
        if (headless) {
                if (argc != 5)
                        eprintf("all positional arguments are mandatory unless 
-h is used\n");
@@ -73,14 +72,12 @@ main(int argc, char *argv[])
                usage();
        }
 
-
        memset(&stream, 0, sizeof(stream));
        stream.file = argv[0];
        stream.fd = eopen(stream.file, O_RDWR);
        if (!headless)
                einit_stream(&stream);
 
-
        if (argc < 2 || !strcmp(argv[1], "auto"))
                frames_auto = 1;
        else
@@ -102,14 +99,12 @@ main(int argc, char *argv[])
        else if (strcmp(argv[4], "same")) {
                if (strlen(argv[4]) >= sizeof(stream.pixfmt))
                        eprintf("choosen pixel format is unsupported\n");
-               strcpy(stream.pixfmt, argv[5]);
-               if (set_pixel_size(&stream))
+               if (set_pixel_format(&stream, argv[5]))
                        eprintf("choosen pixel format is unsupported\n");
        } else if (headless) {
                eprintf("cannot use both 'same' and -h\n");
        }
 
-
        rewrite(&stream, frames_auto);
        close(stream.fd);
        return 0;
diff --git a/src/blind-round-wave.c b/src/blind-round-wave.c
index ac13e2c..d4bfec0 100644
--- a/src/blind-round-wave.c
+++ b/src/blind-round-wave.c
@@ -28,13 +28,7 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&stream);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
        process(&stream);
diff --git a/src/blind-sawtooth-wave.c b/src/blind-sawtooth-wave.c
index 213d261..25e2662 100644
--- a/src/blind-sawtooth-wave.c
+++ b/src/blind-sawtooth-wave.c
@@ -28,13 +28,7 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&stream);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
        process(&stream);
diff --git a/src/blind-set-luma.c b/src/blind-set-luma.c
index 8a14327..2943982 100644
--- a/src/blind-set-luma.c
+++ b/src/blind-set-luma.c
@@ -18,13 +18,7 @@ main(int argc, char *argv[])
        eopen_stream(&colour, NULL);
        eopen_stream(&luma, argv[0]);
 
-       if (!strcmp(colour.pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(colour.pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
colour.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&colour);
        fprint_stream_head(stdout, &colour);
        efflush(stdout, "<stdout>");
        process_two_streams(&colour, &luma, STDOUT_FILENO, "<stdout>", process);
diff --git a/src/blind-sinc-wave.c b/src/blind-sinc-wave.c
index ed36ce8..0f999c5 100644
--- a/src/blind-sinc-wave.c
+++ b/src/blind-sinc-wave.c
@@ -34,12 +34,7 @@ main(int argc, char *argv[])
                        eprintf("theta0-stream must be of dimension 1x1\n");
        }
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
+       SELECT_PROCESS_FUNCTION(&stream);
 
        if (have_theta0 && strcmp(stream.pixfmt, theta0.pixfmt))
                eprintf("videos use incompatible pixel formats\n");
diff --git a/src/blind-sine-wave.c b/src/blind-sine-wave.c
index 82c7794..95a46d6 100644
--- a/src/blind-sine-wave.c
+++ b/src/blind-sine-wave.c
@@ -28,13 +28,7 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&stream);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
        process(&stream);
diff --git a/src/blind-single-colour.c b/src/blind-single-colour.c
index 8017a25..b8f693a 100644
--- a/src/blind-single-colour.c
+++ b/src/blind-single-colour.c
@@ -57,15 +57,9 @@ main(int argc, char *argv[])
        if (inf)
                einf_check_fd(STDOUT_FILENO, "<stdout>");
 
-       pixfmt = get_pixel_format(pixfmt, "xyza");
-       if (!strcmp(pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", pixfmt);
+       eset_pixel_format(&stream, pixfmt);
+       SELECT_PROCESS_FUNCTION(&stream);
 
-       strcpy(stream.pixfmt, pixfmt);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
diff --git a/src/blind-spectrum.c b/src/blind-spectrum.c
index 2086ffc..3ba6191 100644
--- a/src/blind-spectrum.c
+++ b/src/blind-spectrum.c
@@ -33,14 +33,9 @@ main(int argc, char *argv[])
        eopen_stream(&stream, NULL);
        eopen_stream(&spectrum, argv[0]);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
+       SELECT_PROCESS_FUNCTION(&stream);
 
-       if (strcmp(stream.pixfmt, spectrum.pixfmt))
+       if (stream.n_chan != spectrum.n_chan || stream.encoding != 
spectrum.encoding)
                eprintf("videos use incompatible pixel formats\n");
 
        echeck_dimensions(&spectrum, WIDTH | HEIGHT, "spectrum");
diff --git a/src/blind-spiral-gradient.c b/src/blind-spiral-gradient.c
index 3835bf2..a52205d 100644
--- a/src/blind-spiral-gradient.c
+++ b/src/blind-spiral-gradient.c
@@ -52,12 +52,7 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
+       SELECT_PROCESS_FUNCTION(&stream);
 
        if (stream.width > 5 || stream.height > 5 ||
            stream.width * stream.height < 2 ||
@@ -85,7 +80,7 @@ PROCESS(struct stream *stream)
        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;
+       size_t i, ix, iy, ptr = 0;
        for (;;) {
                while (stream->ptr < stream->frame_size) {
                        if (!eread_stream(stream, stream->frame_size - 
stream->ptr)) {
@@ -166,7 +161,8 @@ PROCESS(struct stream *stream)
                                        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;
+                               for (i = 0; i < stream->n_chan; i++)
+                                       buf[ptr][i] = x;
                                if (++ptr == ELEMENTSOF(buf)) {
                                        ewriteall(STDOUT_FILENO, buf, 
sizeof(buf), "<stdout>");
                                        ptr = 0;
diff --git a/src/blind-square-gradient.c b/src/blind-square-gradient.c
index bdd92bc..3a754a2 100644
--- a/src/blind-square-gradient.c
+++ b/src/blind-square-gradient.c
@@ -33,12 +33,7 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
+       SELECT_PROCESS_FUNCTION(&stream);
 
        if (stream.width > 3 || stream.height > 3 ||
            stream.width * stream.height < 2 ||
diff --git a/src/blind-time-blur.c b/src/blind-time-blur.c
index 76ef17b..6827d26 100644
--- a/src/blind-time-blur.c
+++ b/src/blind-time-blur.c
@@ -14,7 +14,7 @@ main(int argc, char *argv[])
 {
        struct stream colour, alpha;
        void (*process)(char *restrict output, char *restrict cbuf, char 
*restrict abuf,
-                       struct stream *colour, struct stream *alpha);
+                       struct stream *colour, struct stream *alpha);
 
        ARGBEGIN {
        default:
@@ -27,13 +27,7 @@ main(int argc, char *argv[])
        eopen_stream(&colour, NULL);
        eopen_stream(&alpha, argv[0]);
 
-       if (colour.encoding == DOUBLE)
-               process = process_lf;
-       else if (colour.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
colour.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&colour);
        echeck_compat(&colour, &alpha);
        fprint_stream_head(stdout, &colour);
        efflush(stdout, "<stdout>");
diff --git a/src/blind-to-portable.c b/src/blind-to-portable.c
index 651c756..2d9c899 100644
--- a/src/blind-to-portable.c
+++ b/src/blind-to-portable.c
@@ -108,18 +108,13 @@ main(int argc, char *argv[])
        default:
                usage();
        } ARGEND;
+
        if (argc)
                usage();
 
        eopen_stream(&stream, NULL);
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported\n", stream.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&stream);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
        process(&stream, strict);
diff --git a/src/blind-to-text.c b/src/blind-to-text.c
index ecae9f2..61bd14d 100644
--- a/src/blind-to-text.c
+++ b/src/blind-to-text.c
@@ -1,18 +1,11 @@
 /* See LICENSE file for copyright and license details. */
+#ifndef TYPE
 #include "common.h"
 
 USAGE("")
 
-#define PROCESS(TYPE, CAST, FMT)\
-       do {\
-               size_t i;\
-               TYPE *p = (TYPE *)(stream->buf);\
-               for (i = 0, n /= stream->chan_size; i < n; i++)\
-                       printf("%"FMT"%c", (CAST)(p[i]), (i + 1) % 
stream->n_chan ? ' ' : '\n');\
-       } while (0)
-
-static void process_lf(struct stream *stream, size_t n) {PROCESS(double, 
double, ".25lf");}
-static void process_f (struct stream *stream, size_t n) {PROCESS(float,  
double, ".25lf");}
+#define FILE "blind-to-text.c"
+#include "define-functions.h"
 
 int
 main(int argc, char *argv[])
@@ -24,16 +17,22 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&stream);
        printf("%zu %zu %zu %s\n", stream.frames, stream.width, stream.height, 
stream.pixfmt);
-
        process_stream(&stream, process);
        efshut(stdout, "<stdout>");
        return 0;
 }
+
+#else
+
+static void
+PROCESS(struct stream *stream, size_t n)
+{
+       size_t i;
+       TYPE *p = (TYPE *)(stream->buf);
+       for (i = 0, n /= stream->chan_size; i < n; i++)
+               printf("%.25"PRINT_TYPE"%c", (PRINT_CAST)(p[i]), (i + 1) % 
stream->n_chan ? ' ' : '\n');
+}
+
+#endif
diff --git a/src/blind-triangle-tessellation.c 
b/src/blind-triangle-tessellation.c
index e4eeb21..8d298f0 100644
--- a/src/blind-triangle-tessellation.c
+++ b/src/blind-triangle-tessellation.c
@@ -4,8 +4,7 @@
 USAGE("[-F pixel-format] block-width block-height")
 
 #define SET_XYZA(TYPE)\
-       (pixwidth *= sizeof(double),\
-        colours = alloca(8 * pixwidth),\
+       (colours = alloca(8 * stream.pixel_size),\
         ((TYPE *)colours)[ 0] = (TYPE)0.412457445582367600,\
         ((TYPE *)colours)[ 1] = (TYPE)0.212673370378408280,\
         ((TYPE *)colours)[ 2] = (TYPE)0.019333942761673460,\
@@ -46,7 +45,6 @@ main(int argc, char *argv[])
 {
        size_t width, height;
        const char *pixfmt = "xyza";
-       size_t pixwidth = 4;
        char *colours;
        size_t x1, y1, x2, y2, k;
 
@@ -64,15 +62,12 @@ main(int argc, char *argv[])
        width  = etozu_arg("block-width",  argv[0], 1, SIZE_MAX);
        height = etozu_arg("block-height", argv[1], 1, SIZE_MAX);
 
-       pixfmt = get_pixel_format(pixfmt, "xyza");
-       if (!strcmp(pixfmt, "xyza"))
+       eset_pixel_format(&stream, pixfmt);
+       if (stream.encoding == DOUBLE)
                SET_XYZA(double);
-       else if (!strcmp(pixfmt, "xyza f"))
-               SET_XYZA(float);
        else
-               eprintf("pixel format %s is not supported, try xyza\n", pixfmt);
+               SET_XYZA(float);
 
-       strcpy(stream.pixfmt, pixfmt);
        stream.width  = 2 * width;
        stream.height = 2 * height;
        fprint_stream_head(stdout, &stream);
@@ -83,7 +78,7 @@ main(int argc, char *argv[])
                        for (x1 = 0; x1 < 2; x1++) {
                                for (x2 = 0; x2 < width; x2++) {
                                        k = y1 * 4 + x1 * 2 + (x2 * height > y2 
* width);
-                                       ewriteall(STDOUT_FILENO, colours + k * 
pixwidth, pixwidth, "<stdout>");
+                                       ewriteall(STDOUT_FILENO, colours + k * 
stream.pixel_size, stream.pixel_size, "<stdout>");
                                }
                        }
                }
diff --git a/src/blind-triangular-wave.c b/src/blind-triangular-wave.c
index b1baf53..7a83a93 100644
--- a/src/blind-triangular-wave.c
+++ b/src/blind-triangular-wave.c
@@ -32,13 +32,7 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (stream.encoding == DOUBLE)
-               process = process_lf;
-       else if (stream.encoding == FLOAT)
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&stream);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
        process(&stream);
diff --git a/src/blind-unpremultiply.c b/src/blind-unpremultiply.c
index 7545af4..d3feced 100644
--- a/src/blind-unpremultiply.c
+++ b/src/blind-unpremultiply.c
@@ -36,13 +36,7 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&stream);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
        process(&stream);
diff --git a/src/blind-vector-projection.c b/src/blind-vector-projection.c
index ea63e3b..a285846 100644
--- a/src/blind-vector-projection.c
+++ b/src/blind-vector-projection.c
@@ -36,13 +36,7 @@ main(int argc, char *argv[])
        eopen_stream(&left, NULL);
        eopen_stream(&right, argv[0]);
 
-       if (!strcmp(left.pixfmt, "xyza"))
-               process = process_lf;
-       else if (!strcmp(left.pixfmt, "xyza f"))
-               process = process_f;
-       else
-               eprintf("pixel format %s is not supported, try xyza\n", 
left.pixfmt);
-
+       SELECT_PROCESS_FUNCTION(&left);
        fprint_stream_head(stdout, &left);
        efflush(stdout, "<stdout>");
        process_two_streams(&left, &right, STDOUT_FILENO, "<stdout>", process);
diff --git a/src/common.h b/src/common.h
index 6113edf..7d253c0 100644
--- a/src/common.h
+++ b/src/common.h
@@ -68,3 +68,11 @@
 #if !defined(PIPE_BUF)
 # define PIPE_BUF BUFSIZ
 #endif
+
+#define SELECT_PROCESS_FUNCTION(stream)\
+       do {\
+               if ((stream)->encoding == DOUBLE)\
+                       process = process_lf;\
+               else\
+                       process = process_f;\
+       } while (0)
diff --git a/src/define-functions.h b/src/define-functions.h
index 4952fe0..3a44829 100644
--- a/src/define-functions.h
+++ b/src/define-functions.h
@@ -2,12 +2,24 @@
 
 #define PROCESS process_lf
 #define TYPE double
+#define SCAN_TYPE "lf"
+#define PRINT_TYPE "lf"
+#define PRINT_CAST double
 #include FILE
 #undef PROCESS
 #undef TYPE
+#undef SCAN_TYPE
+#undef PRINT_TYPE
+#undef PRINT_CAST
 
 #define PROCESS process_f
 #define TYPE float
+#define SCAN_TYPE "f"
+#define PRINT_TYPE "lf"
+#define PRINT_CAST double
 #include FILE
 #undef PROCESS
 #undef TYPE
+#undef SCAN_TYPE
+#undef PRINT_TYPE
+#undef PRINT_CAST
diff --git a/src/stream.c b/src/stream.c
index 7ce32e2..11dabd5 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -73,7 +73,7 @@ eninit_stream(int status, struct stream *stream)
        memmove(stream->buf, stream->buf + 5, stream->ptr -= 5);
        stream->headlen = n + 5;
 
-       enset_pixel_size(status, stream);
+       enset_pixel_format(status, stream, NULL);
 
        stream->xptr = 0;
 
@@ -93,8 +93,15 @@ enopen_stream(int status, struct stream *stream, const char 
*file)
 
 
 int
-set_pixel_size(struct stream *stream)
+set_pixel_format(struct stream *stream, const char *pixfmt)
 {
+       if (pixfmt) {
+               pixfmt = get_pixel_format(pixfmt, "xyza");
+               if (strlen(pixfmt) >= sizeof(stream->pixfmt))
+                       return -1;
+               strcpy(stream->pixfmt, pixfmt);
+       }
+
        if (!strcmp(stream->pixfmt, "xyza")) {
                stream->n_chan = 4;
                stream->chan_size = sizeof(double);
@@ -110,6 +117,7 @@ set_pixel_size(struct stream *stream)
        } else {
                return -1;
        }
+
        stream->pixel_size = stream->n_chan * stream->chan_size;
        stream->row_size   = stream->pixel_size * stream->width;
        stream->col_size   = stream->pixel_size * stream->height;
@@ -118,11 +126,15 @@ set_pixel_size(struct stream *stream)
 }
 
 void
-enset_pixel_size(int status, struct stream *stream)
+enset_pixel_format(int status, struct stream *stream, const char *pixfmt)
 {
-       if (set_pixel_size(stream))
-               enprintf(status, "file %s uses unsupported pixel format: %s\n",
-                        stream->file, stream->pixfmt);
+       if (!set_pixel_format(stream, pixfmt)) {
+               if (pixfmt)
+                       enprintf(status, "pixel format %s is not supported, try 
xyza\n", pixfmt);
+               else
+                       enprintf(status, "%s: unsupported pixel format: %s\n",
+                                stream->file, stream->pixfmt);
+       }
 }
 
 
diff --git a/src/stream.h b/src/stream.h
index f04918a..b85c6c6 100644
--- a/src/stream.h
+++ b/src/stream.h
@@ -37,7 +37,7 @@
 
 #define einit_stream(...)             eninit_stream(1, __VA_ARGS__)
 #define eopen_stream(...)             enopen_stream(1, __VA_ARGS__)
-#define eset_pixel_size(...)          enset_pixel_size(1, __VA_ARGS__)
+#define eset_pixel_format(...)        enset_pixel_format(1, __VA_ARGS__)
 #define eread_stream(...)             enread_stream(1, __VA_ARGS__)
 #define einf_check_fd(...)            eninf_check_fd(1, __VA_ARGS__)
 #define echeck_dimensions(...)        encheck_dimensions(1, __VA_ARGS__)
@@ -100,8 +100,8 @@ struct stream {
 
 void eninit_stream(int status, struct stream *stream);
 void enopen_stream(int status, struct stream *stream, const char *file);
-int set_pixel_size(struct stream *stream);
-void enset_pixel_size(int status, struct stream *stream);
+int set_pixel_format(struct stream *stream, const char *pixfmt);
+void enset_pixel_format(int status, struct stream *stream, const char *pixfmt);
 void fprint_stream_head(FILE *fp, struct stream *stream);
 int dprint_stream_head(int fd, struct stream *stream);
 size_t enread_stream(int status, struct stream *stream, size_t n);

Reply via email to