commit 3569a10c97d41913dbf7cf3114cb4d2d5f17dc7f
Author:     Mattias Andrée <[email protected]>
AuthorDate: Sat Jul 15 17:08:02 2017 +0200
Commit:     Mattias Andrée <[email protected]>
CommitDate: Sat Jul 15 17:08:02 2017 +0200

    Some improvements and fixes
    
    Signed-off-by: Mattias Andrée <[email protected]>

diff --git a/TODO b/TODO
index 9288654..d203041 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,5 @@
+Fix blind-from-named without command
+
 blind-transform                affine transformation by matrix multiplication, 
-t for tiling, -s for
                                improve quality on downscaling (pixels' 
neighbours must not change).
 blind-primary-key      replace a primary with transparency, -g for greyscaled 
images.
diff --git a/man/blind-invert-matrix.1 b/man/blind-invert-matrix.1
index e239762..d1f2dbc 100644
--- a/man/blind-invert-matrix.1
+++ b/man/blind-invert-matrix.1
@@ -21,11 +21,6 @@ resuling augment is printed.
 .B -e
 Apply optimisation that assumes all channels
 are identical.
-.SH NOTES
-.B blind-invert-matrix
-fails if it encounters a non-invertable
-matrix, however, this is not always the
-case.
 .SH SEE ALSO
 .BR blind (7),
 .BR blind-multiply-matrices (1),
diff --git a/src/blind-apply-palette.c b/src/blind-apply-palette.c
index e75b31c..1e0d5f8 100644
--- a/src/blind-apply-palette.c
+++ b/src/blind-apply-palette.c
@@ -3,11 +3,9 @@
 
 USAGE("palette-stream")
 
-
 static double (*compare)(double x1, double y1, double z1, double a1, double 
x2, double y2, double z2, double a2);
 /* TODO add more formulae: https://en.wikipedia.org/wiki/Color_difference */
 
-
 static double
 distance_xyz(double x1, double y1, double z1, double a1, double x2, double y2, 
double z2, double a2)
 {
@@ -18,7 +16,6 @@ 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)\
@@ -69,7 +66,6 @@ distance_xyz(double x1, double y1, double z1, double a1, 
double x2, double y2, d
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
diff --git a/src/blind-chroma-key.c b/src/blind-chroma-key.c
index 602457e..b9deadb 100644
--- a/src/blind-chroma-key.c
+++ b/src/blind-chroma-key.c
@@ -3,7 +3,6 @@
 
 USAGE("key-stream")
 
-
 #define PROCESS(TYPE, SUFFIX)\
        static void\
        process_##SUFFIX(struct stream *stream, struct stream *key)\
@@ -61,7 +60,6 @@ USAGE("key-stream")
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
diff --git a/src/blind-colour-ciexyz.c b/src/blind-colour-ciexyz.c
index 64f48c5..9710074 100644
--- a/src/blind-colour-ciexyz.c
+++ b/src/blind-colour-ciexyz.c
@@ -14,7 +14,7 @@ main(int argc, char *argv[])
                Y = etolf_arg("the Y value", argv[0]);
                X = Y * D65_XYZ_X;
                Z = Y * D65_XYZ_Z;
-               printf("%lf %lf %lf\n", X, Y, Z);
+               printf("%.50lf %.50lf %.50lf\n", X, Y, Z);
        } else if (argc == 3) {
                printf("%s %s %s\n", argv[0], argv[1], argv[2]);
        } else {
diff --git a/src/blind-colour-srgb.c b/src/blind-colour-srgb.c
index 3a23a0f..e5d1925 100644
--- a/src/blind-colour-srgb.c
+++ b/src/blind-colour-srgb.c
@@ -36,7 +36,7 @@ main(int argc, char *argv[])
        }
 
        srgb_to_ciexyz(red, green, blue, &X, &Y, &Z);
-       printf("%lf %lf %lf\n", X, Y, Z);
+       printf("%.50lf %.50lf %.50lf\n", X, Y, Z);
        efshut(stdout, "<stdout>");
        return 0;
 }
diff --git a/src/blind-cone-gradient.c b/src/blind-cone-gradient.c
index 23906e0..fc23210 100644
--- a/src/blind-cone-gradient.c
+++ b/src/blind-cone-gradient.c
@@ -9,7 +9,6 @@ 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)\
@@ -74,7 +73,6 @@ static int with_multiplier = 0;
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
diff --git a/src/blind-cross-product.c b/src/blind-cross-product.c
index ca5fcdf..5f79424 100644
--- a/src/blind-cross-product.c
+++ b/src/blind-cross-product.c
@@ -39,9 +39,9 @@ main(int argc, char *argv[])
        eopen_stream(&left, NULL);
        eopen_stream(&right, argv[0]);
 
-       if (!strcmp(left.pixfmt, "xyza"))
+       if (left.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(left.pixfmt, "xyza f"))
+       else if (left.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
left.pixfmt);
diff --git a/src/blind-dot-product.c b/src/blind-dot-product.c
index a618ca7..b9699c2 100644
--- a/src/blind-dot-product.c
+++ b/src/blind-dot-product.c
@@ -7,14 +7,16 @@ USAGE("right-hand-stream")
        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;\
-               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;\
-                       *lx = *ly = *lz = *la = *lx * *rx + *ly * *ry + *lz * 
*rz + *la * *ra;\
+               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;\
                }\
        }
 
@@ -32,9 +34,9 @@ main(int argc, char *argv[])
        eopen_stream(&left, NULL);
        eopen_stream(&right, argv[0]);
 
-       if (!strcmp(left.pixfmt, "xyza"))
+       if (left.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(left.pixfmt, "xyza f"))
+       else if (left.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
left.pixfmt);
diff --git a/src/blind-double-sine-wave.c b/src/blind-double-sine-wave.c
index a2bec66..e10cf1e 100644
--- a/src/blind-double-sine-wave.c
+++ b/src/blind-double-sine-wave.c
@@ -5,51 +5,34 @@ USAGE("[-e]")
 
 static int equal = 0;
 
-
 #define PROCESS(TYPE, SUFFIX)\
        static void\
        process_##SUFFIX(struct stream *stream)\
        {\
-               size_t i, n;\
-               TYPE x, y, z, a;\
+               size_t i, j, n;\
+               TYPE v, *p;\
                do {\
-                       n = stream->ptr / stream->pixel_size;\
                        if (equal) {\
+                               n = stream->ptr / stream->pixel_size;\
                                for (i = 0; i < n; i++) {\
-                                       a = ((TYPE *)(stream->buf))[4 * i + 3];\
-                                       a = posmod(a, (TYPE)2);\
-                                       a = a > 1 ? 2 - a : a;\
-                                       a = 1 - (sin(a * (2 * (TYPE)M_PI)) + 1) 
/ 2;\
-                                       ((TYPE *)(stream->buf))[4 * i + 0] = a;\
-                                       ((TYPE *)(stream->buf))[4 * i + 1] = a;\
-                                       ((TYPE *)(stream->buf))[4 * i + 2] = a;\
-                                       ((TYPE *)(stream->buf))[4 * i + 3] = a;\
+                                       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++) {\
-                                       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];\
-                                       x = posmod(x, (TYPE)1);\
-                                       y = posmod(y, (TYPE)1);\
-                                       z = posmod(z, (TYPE)1);\
-                                       a = posmod(a, (TYPE)1);\
-                                       x = x > 1 ? 2 - x : x;\
-                                       y = y > 1 ? 2 - y : y;\
-                                       z = z > 1 ? 2 - z : z;\
-                                       a = a > 1 ? 2 - a : a;\
-                                       x = 1 - (sin(x * (2 * (TYPE)M_PI)) + 1) 
/ 2;\
-                                       y = 1 - (sin(y * (2 * (TYPE)M_PI)) + 1) 
/ 2;\
-                                       z = 1 - (sin(z * (2 * (TYPE)M_PI)) + 1) 
/ 2;\
-                                       a = 1 - (sin(a * (2 * (TYPE)M_PI)) + 1) 
/ 2;\
-                                       ((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;\
+                                       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;\
                        }\
-                       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));\
@@ -60,7 +43,6 @@ static int equal = 0;
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
@@ -80,9 +62,9 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
+       if (stream.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
+       else if (stream.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
diff --git a/src/blind-extract-alpha.c b/src/blind-extract-alpha.c
index ac27724..f65042a 100644
--- a/src/blind-extract-alpha.c
+++ b/src/blind-extract-alpha.c
@@ -8,17 +8,17 @@ USAGE("colour-file")
        process_##SUFFIX(struct stream *stream, int fd, const char *fname)\
        {\
                char buf[sizeof(stream->buf)];\
-               size_t i, n;\
-               TYPE a;\
+               size_t i, j, n;\
+               TYPE a, *p, *b;\
                do {\
                        n = stream->ptr / stream->pixel_size;\
-                       for (i = 0; i < n; i++) {\
-                               a = ((TYPE *)(stream->buf))[4 * i + 3];\
-                               ((TYPE *)(stream->buf))[4 * i + 3] = 1;\
-                               ((TYPE *)buf)[4 * i + 0] = a;\
-                               ((TYPE *)buf)[4 * i + 1] = a;\
-                               ((TYPE *)buf)[4 * i + 2] = a;\
-                               ((TYPE *)buf)[4 * i + 3] = 1;\
+                       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);\
@@ -32,7 +32,6 @@ USAGE("colour-file")
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
@@ -45,9 +44,9 @@ main(int argc, char *argv[])
        eopen_stream(&stream, NULL);
        fd = eopen(argv[0], O_WRONLY | O_CREAT | O_TRUNC, 0666);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
+       if (stream.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
+       else if (stream.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
diff --git a/src/blind-find-rectangle.c b/src/blind-find-rectangle.c
index 51b164c..a71e7e9 100644
--- a/src/blind-find-rectangle.c
+++ b/src/blind-find-rectangle.c
@@ -111,13 +111,13 @@ main(int argc, char *argv[])
        cache = emalloc2(stream.width + 1, sizeof(*cache));
        buf   = emalloc(stream.row_size);
 
-       if (!strcmp(stream.pixfmt, "xyza")) {
+       if (stream.encoding == DOUBLE) {
                colour_lf[0] = X;
                colour_lf[1] = Y;
                colour_lf[2] = Z;
                colour_lf[3] = alpha;
                process(colour_lf);
-       } else if (!strcmp(stream.pixfmt, "xyza f")) {
+       } else if (stream.encoding == FLOAT) {
                colour_f[0] = (float)X;
                colour_f[1] = (float)Y;
                colour_f[2] = (float)Z;
diff --git a/src/blind-from-portable.c b/src/blind-from-portable.c
index 5510df5..6e24100 100644
--- a/src/blind-from-portable.c
+++ b/src/blind-from-portable.c
@@ -72,10 +72,10 @@ USAGE("[-s]")
        } while (0)
 
 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 float  conv_float (uint32_t portable) {CONV(uint32_t, int32_t, float,   
8,  127, 23);}
 
-static void process_xyza (struct stream *stream, int strict) 
{PROCESS(uint64_t, double, 64);}
-static void process_xyzaf(struct stream *stream, int strict) 
{PROCESS(uint32_t, float, 32);}
+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);}
 
 int
 main(int argc, char *argv[])
@@ -96,10 +96,10 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_xyza;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_xyzaf;
+       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);
 
diff --git a/src/blind-from-text.c b/src/blind-from-text.c
index f2eaaa5..4bf41f7 100644
--- a/src/blind-from-text.c
+++ b/src/blind-from-text.c
@@ -20,8 +20,8 @@ USAGE("")
                }\
        } while (0)
 
-static void process_xyza (void) {PROCESS(double, "lf");}
-static void process_xyzaf(void) {PROCESS(float, "f");}
+static void process_lf(void) { PROCESS(double, "lf"); }
+static void process_f(void)  { PROCESS(float,  "f");  }
 
 int
 main(int argc, char *argv[])
@@ -54,10 +54,10 @@ main(int argc, char *argv[])
        ewriteall(STDOUT_FILENO, stream.buf, stream.ptr, "<stdout>");
        einit_stream(&stream);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_xyza;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_xyzaf;
+       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);
 
diff --git a/src/blind-get-colours.c b/src/blind-get-colours.c
index 87d94b9..ba7c8ef 100644
--- a/src/blind-get-colours.c
+++ b/src/blind-get-colours.c
@@ -3,17 +3,14 @@
 
 USAGE("")
 
-
 static size_t width;
 
-
 static int
 pixcmp(const void *a, const void *b)
 {
        return memcmp(a, b, width);
 }
 
-
 static size_t
 unique(char *base, size_t n)
 {
@@ -24,7 +21,6 @@ unique(char *base, size_t n)
        return r;
 }
 
-
 static size_t
 merge(char **sink, size_t n, char *new, size_t m, size_t *siz)
 {
@@ -52,7 +48,6 @@ merge(char **sink, size_t n, char *new, size_t m, size_t *siz)
        return n + m;
 }
 
-
 int
 main(int argc, char *argv[])
 {
diff --git a/src/blind-invert-matrix.c b/src/blind-invert-matrix.c
index 32cc119..9befe67 100644
--- a/src/blind-invert-matrix.c
+++ b/src/blind-invert-matrix.c
@@ -10,7 +10,7 @@ static int equal = 0;
                p2 = matrix + r2 * cn;\
                t = p2[r1][0];\
                for (c = 0; c < cn; c++)\
-                       p1[c][0] -= p2[c][0] * t;\
+                       p2[c][0] -= p1[c][0] * t;\
        } while (0)
 
 #define PROCESS(TYPE)\
@@ -34,9 +34,9 @@ static int equal = 0;
                                for (c = 0; c < cn; c++)\
                                        t = p1[c][0], p1[c][0] = p2[c][0], 
p2[c][0] = t;\
                        }\
-                       t = p1[r1][0];\
+                       t = 1 / p1[r1][0];\
                        for (c = 0; c < cn; c++)\
-                               p1[c][0] /= t;\
+                               p1[c][0] *= t;\
                        for (r2 = r1 + 1; r2 < rn; r2++)\
                                SUB_ROWS();\
                }\
@@ -55,7 +55,7 @@ int
 main(int argc, char *argv[])
 {
        struct stream stream;
-       size_t width, x, y, row_size, chan_size;
+       size_t width, x, y, row_size;
        char *buf, *one = alloca(4 * sizeof(double)), *p;
        void (*process)(struct stream *stream, void *buf);
 
@@ -81,22 +81,20 @@ main(int argc, char *argv[])
        stream.width = width;
        efflush(stdout, "<stdout>");
 
+       one = alloca(stream.pixel_size);
        if (!strcmp(stream.pixfmt, "xyza")) {
-               one = alloca(4 * sizeof(double));
                *(double *)one = 1;
                process = process_lf;
        } else if (!strcmp(stream.pixfmt, "xyza f")) {
-               one = alloca(4 * sizeof(float));
                *(float *)one = 1;
                process = process_f;
        } else {
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
        }
 
-       chan_size = stream.pixel_size / 4;
-       memcpy(one + 1 * chan_size, one, chan_size);
-       memcpy(one + 2 * chan_size, one, chan_size);
-       memcpy(one + 3 * chan_size, one, chan_size);
+       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);
 
        width = stream.width > stream.height ? stream.width : 2 * stream.height;
        buf = emalloc2(width, stream.col_size);
@@ -111,19 +109,19 @@ main(int argc, char *argv[])
                        }
                }
                if (equal) {
-                       process(&stream, buf + 1 * chan_size);
+                       process(&stream, buf + 1 * stream.chan_size);
                        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 + chan_size, chan_size);
-                                       memcpy(p + 2 * chan_size, p, 2 * 
chan_size);
+                                       memcpy(p, p + stream.chan_size, 
stream.chan_size);
+                                       memcpy(p + 2 * stream.chan_size, p, 2 * 
stream.chan_size);
                                }
                        }
                } else {
-                       process(&stream, buf + 0 * chan_size);
-                       process(&stream, buf + 1 * chan_size);
-                       process(&stream, buf + 2 * chan_size);
-                       process(&stream, buf + 3 * chan_size);
+                       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 (y = 0; y < stream.height; y++)
                        ewriteall(STDOUT_FILENO, buf + y * row_size + 
stream.col_size, row_size - stream.col_size, "<stdout>");
diff --git a/src/blind-linear-gradient.c b/src/blind-linear-gradient.c
index dce6894..1865ae6 100644
--- a/src/blind-linear-gradient.c
+++ b/src/blind-linear-gradient.c
@@ -7,7 +7,6 @@ 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)\
@@ -56,7 +55,6 @@ static size_t height = 0;
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
diff --git a/src/blind-matrix-orthoproject.c b/src/blind-matrix-orthoproject.c
index 2fe82a2..4a9cb3c 100644
--- a/src/blind-matrix-orthoproject.c
+++ b/src/blind-matrix-orthoproject.c
@@ -11,9 +11,9 @@ static int per_channel = 0;
                pixel_t matrix[9];\
                pixel_t buf[2];\
                TYPE x2, y2, norm2;\
-               int i;\
+               size_t i;\
                \
-               for (i = 0; i < 4; 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;\
@@ -21,7 +21,7 @@ static int per_channel = 0;
                \
                while (eread_frame(stream, buf)) {\
                        if (per_channel) {\
-                               for (i = 0; i < 4; i++) {\
+                               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;\
@@ -38,10 +38,12 @@ static int per_channel = 0;
                                matrix[0][0] = x2 / norm2;\
                                matrix[4][0] = y2 / norm2;\
                                matrix[3][0] = matrix[1][0] = buf[0][1] * 
buf[1][1] / norm2;\
-                               matrix[0][3] = matrix[0][2] = matrix[0][1] = 
matrix[0][0];\
-                               matrix[1][3] = matrix[1][2] = matrix[1][1] = 
matrix[1][0];\
-                               matrix[3][3] = matrix[3][2] = matrix[3][1] = 
matrix[3][0];\
-                               matrix[4][3] = matrix[4][2] = matrix[4][1] = 
matrix[4][0];\
+                               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>");\
                }\
@@ -77,9 +79,9 @@ main(int argc, char *argv[])
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       if (!strcmp(stream.pixfmt, "xyza"))
+       if (stream.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
+       else if (stream.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
diff --git a/src/blind-matrix-reflect.c b/src/blind-matrix-reflect.c
index 905ec96..ef882b5 100644
--- a/src/blind-matrix-reflect.c
+++ b/src/blind-matrix-reflect.c
@@ -11,9 +11,9 @@ static int per_channel = 0;
                pixel_t matrix[9];\
                pixel_t buf[2];\
                TYPE x2, y2, norm2;\
-               int i;\
+               size_t i;\
                \
-               for (i = 0; i < 4; 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;\
@@ -21,7 +21,7 @@ static int per_channel = 0;
                \
                while (eread_frame(stream, buf)) {\
                        if (per_channel) {\
-                               for (i = 0; i < 4; i++) {\
+                               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;\
@@ -36,10 +36,12 @@ static int per_channel = 0;
                                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;\
-                               matrix[0][3] = matrix[0][2] = matrix[0][1] = 
matrix[0][0];\
-                               matrix[1][3] = matrix[1][2] = matrix[1][1] = 
matrix[1][0];\
-                               matrix[3][3] = matrix[3][2] = matrix[3][1] = 
matrix[3][0];\
-                               matrix[4][3] = matrix[4][2] = matrix[4][1] = 
matrix[4][0];\
+                               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>");\
                }\
@@ -75,9 +77,9 @@ main(int argc, char *argv[])
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       if (!strcmp(stream.pixfmt, "xyza"))
+       if (stream.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
+       else if (stream.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
diff --git a/src/blind-matrix-rotate.c b/src/blind-matrix-rotate.c
index 0b0fc18..486616e 100644
--- a/src/blind-matrix-rotate.c
+++ b/src/blind-matrix-rotate.c
@@ -11,9 +11,9 @@ static int in_degrees = 0;
                typedef TYPE pixel_t[4];\
                pixel_t matrix[9];\
                pixel_t buf;\
-               int i;\
+               size_t i;\
                \
-               for (i = 0; i < 4; 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;\
@@ -21,12 +21,12 @@ static int in_degrees = 0;
                \
                while (eread_frame(stream, buf)) {\
                        if (per_channel && in_degrees) {\
-                               for (i = 0; i < 4; i++) {\
+                               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 < 4; i++) {\
+                               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]));\
                                }\
@@ -39,10 +39,12 @@ static int in_degrees = 0;
                                        matrix[4][0] = matrix[0][0] = 
cos(buf[1]);\
                                        matrix[3][0] = -(matrix[1][0] = 
sin(buf[1]));\
                                }\
-                               matrix[0][3] = matrix[0][2] = matrix[0][1] = 
matrix[0][0];\
-                               matrix[1][3] = matrix[1][2] = matrix[1][1] = 
matrix[1][0];\
-                               matrix[3][3] = matrix[3][2] = matrix[3][1] = 
matrix[3][0];\
-                               matrix[4][3] = matrix[4][2] = matrix[4][1] = 
matrix[4][0];\
+                               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>");\
                }\
@@ -81,9 +83,9 @@ main(int argc, char *argv[])
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       if (!strcmp(stream.pixfmt, "xyza"))
+       if (stream.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
+       else if (stream.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
diff --git a/src/blind-matrix-scale.c b/src/blind-matrix-scale.c
index 8dd6b83..5675a8e 100644
--- a/src/blind-matrix-scale.c
+++ b/src/blind-matrix-scale.c
@@ -10,9 +10,9 @@ static int per_channel = 0;
                typedef TYPE pixel_t[4];\
                pixel_t matrix[9];\
                pixel_t buf[2];\
-               int i;\
+               size_t i;\
                \
-               for (i = 0; i < 4; 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;\
@@ -20,13 +20,17 @@ static int per_channel = 0;
                \
                while (eread_frame(stream, buf)) {\
                        if (per_channel) {\
-                               for (i = 0; i < 4; i++) {\
+                               for (i = 0; i < stream->n_chan; i++) {\
                                        matrix[0][i] = buf[0][i];\
                                        matrix[4][i] = buf[1][i];\
                                }\
                        } else {\
-                               matrix[0][3] = matrix[0][2] = matrix[0][1] = 
matrix[0][0] = buf[0][1] * buf[0][3];\
-                               matrix[4][3] = matrix[4][2] = matrix[4][1] = 
matrix[4][0] = buf[1][1] * buf[1][3];\
+                               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>");\
                }\
@@ -62,9 +66,9 @@ main(int argc, char *argv[])
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       if (!strcmp(stream.pixfmt, "xyza"))
+       if (stream.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
+       else if (stream.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
diff --git a/src/blind-matrix-shear.c b/src/blind-matrix-shear.c
index 0a4310e..e6a7d2d 100644
--- a/src/blind-matrix-shear.c
+++ b/src/blind-matrix-shear.c
@@ -13,9 +13,9 @@ static int in_degrees = 0;
                pixel_t matrix[9];\
                pixel_t buf[2];\
                TYPE conv = in_degrees ? (TYPE)(M_PI / 180.) : 1;\
-               int i;\
+               size_t i;\
                \
-               for (i = 0; i < 4; 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;\
@@ -23,19 +23,23 @@ static int in_degrees = 0;
                \
                while (eread_frame(stream, buf)) {\
                        if (by_angle) {\
-                               for (i = !per_channel; i < (per_channel ? 4 : 
2); i++) {\
+                               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 < 4; i++) {\
+                               for (i = 0; i < stream->n_chan; i++) {\
                                        matrix[1][i] = buf[0][i];\
                                        matrix[3][i] = buf[1][i];\
                                }\
                        } else {\
-                               matrix[1][3] = matrix[1][2] = matrix[1][1] = 
matrix[1][0] = buf[0][1] * buf[0][3];\
-                               matrix[3][3] = matrix[3][2] = matrix[3][1] = 
matrix[3][0] = buf[1][1] * buf[1][3];\
+                               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>");\
                }\
@@ -77,9 +81,9 @@ main(int argc, char *argv[])
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       if (!strcmp(stream.pixfmt, "xyza"))
+       if (stream.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
+       else if (stream.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
diff --git a/src/blind-matrix-translate.c b/src/blind-matrix-translate.c
index c761a7f..d062615 100644
--- a/src/blind-matrix-translate.c
+++ b/src/blind-matrix-translate.c
@@ -10,9 +10,9 @@ static int per_channel = 0;
                typedef TYPE pixel_t[4];\
                pixel_t matrix[9];\
                pixel_t buf[2];\
-               int i;\
+               size_t i;\
                \
-               for (i = 0; i < 4; 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;\
@@ -20,13 +20,17 @@ static int per_channel = 0;
                \
                while (eread_frame(stream, buf)) {\
                        if (per_channel) {\
-                               for (i = 0; i < 4; i++) {\
+                               for (i = 0; i < stream->n_chan; i++) {\
                                        matrix[2][i] = buf[0][i];\
                                        matrix[5][i] = buf[1][i];\
                                }\
                        } else {\
-                               matrix[2][3] = matrix[2][2] = matrix[2][1] = 
matrix[2][0] = buf[0][1] * buf[0][3];\
-                               matrix[5][3] = matrix[5][2] = matrix[5][1] = 
matrix[5][0] = buf[1][1] * buf[1][3];\
+                               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>");\
                }\
@@ -62,9 +66,9 @@ main(int argc, char *argv[])
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       if (!strcmp(stream.pixfmt, "xyza"))
+       if (stream.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
+       else if (stream.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
diff --git a/src/blind-matrix-transpose.c b/src/blind-matrix-transpose.c
index 5c417db..f24d0a7 100644
--- a/src/blind-matrix-transpose.c
+++ b/src/blind-matrix-transpose.c
@@ -10,9 +10,9 @@ static int per_channel = 0;
                typedef TYPE pixel_t[4];\
                pixel_t matrix[9];\
                pixel_t buf;\
-               int i;\
+               size_t i;\
                \
-               for (i = 0; i < 4; 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;\
@@ -20,13 +20,14 @@ static int per_channel = 0;
                \
                while (eread_frame(stream, buf)) {\
                        if (per_channel) {\
-                               for (i = 0; i < 4; i++) {\
+                               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 {\
-                               for (i = 0; i < 4; i++) {\
-                                       matrix[3][i] = matrix[1][i] = buf[1] * 
buf[3];\
+                               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];\
                                }\
                        }\
@@ -64,9 +65,9 @@ main(int argc, char *argv[])
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       if (!strcmp(stream.pixfmt, "xyza"))
+       if (stream.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
+       else if (stream.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
diff --git a/src/blind-multiply-matrices.c b/src/blind-multiply-matrices.c
index 9eeb23f..5c70d4b 100644
--- a/src/blind-multiply-matrices.c
+++ b/src/blind-multiply-matrices.c
@@ -30,15 +30,16 @@ static size_t max_frame_size;
                                        for (y = r = 0; y < h2; y++) {\
                                                for (x = 0; x < w; x++, r++) {\
                                                        for (k = 0; k < h; k++) 
\
-                                                               res[r][1] += 
left[y * h + k][1] * right[k * w + x][1];\
-                                                       res[r][3] = res[r][2] = 
res[r][0] = res[r][1];\
+                                                               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 < 
4; j++)\
+                                                               for (j = 0; j < 
streams->n_chan; j++)\
                                                                        
res[r][j] += left[y * h + k][j] * right[k * w + x][j];\
                                }\
                                \
@@ -112,9 +113,9 @@ main(int argc, char *argv[])
                height = streams[i].height;
        }
 
-       if (!strcmp(streams->pixfmt, "xyza"))
+       if (streams->encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(streams->pixfmt, "xyza f"))
+       else if (streams->encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
streams->pixfmt);
diff --git a/src/blind-norm.c b/src/blind-norm.c
index c4d04a0..13db67c 100644
--- a/src/blind-norm.c
+++ b/src/blind-norm.c
@@ -8,7 +8,6 @@ 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)\
@@ -43,7 +42,6 @@ static int skip_z = 0;
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
diff --git a/src/blind-premultiply.c b/src/blind-premultiply.c
index 3f34f05..3d9065a 100644
--- a/src/blind-premultiply.c
+++ b/src/blind-premultiply.c
@@ -7,7 +7,6 @@ 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)\
@@ -36,7 +35,6 @@ static int skip_z = 0;
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
diff --git a/src/blind-quaternion-product.c b/src/blind-quaternion-product.c
index 1eedb7d..02bed9d 100644
--- a/src/blind-quaternion-product.c
+++ b/src/blind-quaternion-product.c
@@ -39,9 +39,9 @@ main(int argc, char *argv[])
        eopen_stream(&left, NULL);
        eopen_stream(&right, argv[0]);
 
-       if (!strcmp(left.pixfmt, "xyza"))
+       if (left.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(left.pixfmt, "xyza f"))
+       else if (left.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
left.pixfmt);
diff --git a/src/blind-radial-gradient.c b/src/blind-radial-gradient.c
index 0c4571c..ce20366 100644
--- a/src/blind-radial-gradient.c
+++ b/src/blind-radial-gradient.c
@@ -7,7 +7,6 @@ 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)\
@@ -82,7 +81,6 @@ static int with_params;
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
diff --git a/src/blind-round-wave.c b/src/blind-round-wave.c
index 00a30e1..5aa3026 100644
--- a/src/blind-round-wave.c
+++ b/src/blind-round-wave.c
@@ -5,46 +5,32 @@ USAGE("[-e]")
 
 static int equal = 0;
 
-
 #define PROCESS(TYPE, SUFFIX)\
        static void\
        process_##SUFFIX(struct stream *stream)\
        {\
-               size_t i, n;\
-               TYPE x, y, z, a;\
+               size_t i, j, n;\
+               TYPE v, *p;\
                do {\
-                       n = stream->ptr / stream->pixel_size;\
                        if (equal) {\
+                               n = stream->ptr / stream->pixel_size;\
                                for (i = 0; i < n; i++) {\
-                                       a = ((TYPE *)(stream->buf))[4 * i + 3];\
-                                       a = mod(a + 1, (TYPE)4) - 1;\
-                                       a = a < 1 ? 1 - a * a / 2 : (a - 2) * 
(a - 2) / 2;\
-                                       ((TYPE *)(stream->buf))[4 * i + 0] = a;\
-                                       ((TYPE *)(stream->buf))[4 * i + 1] = a;\
-                                       ((TYPE *)(stream->buf))[4 * i + 2] = a;\
-                                       ((TYPE *)(stream->buf))[4 * i + 3] = a;\
+                                       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++) {\
-                                       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];\
-                                       x = mod(x + 1, (TYPE)4) - 1;\
-                                       y = mod(y + 1, (TYPE)4) - 1;\
-                                       z = mod(z + 1, (TYPE)4) - 1;\
-                                       a = mod(a + 1, (TYPE)4) - 1;\
-                                       x = x < 1 ? 1 - x * x / 2 : (x - 2) * 
(x - 2) / 2;\
-                                       y = y < 1 ? 1 - y * y / 2 : (y - 2) * 
(y - 2) / 2;\
-                                       z = z < 1 ? 1 - z * z / 2 : (z - 2) * 
(z - 2) / 2;\
-                                       a = a < 1 ? 1 - a * a / 2 : (a - 2) * 
(a - 2) / 2;\
-                                       ((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;\
+                                       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;\
                        }\
-                       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));\
@@ -55,7 +41,6 @@ static int equal = 0;
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
@@ -75,9 +60,9 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
+       if (stream.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
+       else if (stream.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
diff --git a/src/blind-sawtooth-wave.c b/src/blind-sawtooth-wave.c
index a4ecfb4..d1eeec1 100644
--- a/src/blind-sawtooth-wave.c
+++ b/src/blind-sawtooth-wave.c
@@ -5,41 +5,30 @@ USAGE("[-e]")
 
 static int equal = 0;
 
-
 #define PROCESS(TYPE, SUFFIX)\
        static void\
        process_##SUFFIX(struct stream *stream)\
        {\
-               size_t i, n;\
-               TYPE x, y, z, a;\
+               size_t i, j, n;\
+               TYPE v, *p;\
                do {\
-                       n = stream->ptr / stream->pixel_size;\
                        if (equal) {\
+                               n = stream->ptr / stream->pixel_size;\
                                for (i = 0; i < n; i++) {\
-                                       a = ((TYPE *)(stream->buf))[4 * i + 3];\
-                                       a = posmod(a, (TYPE)1);\
-                                       ((TYPE *)(stream->buf))[4 * i + 0] = a;\
-                                       ((TYPE *)(stream->buf))[4 * i + 1] = a;\
-                                       ((TYPE *)(stream->buf))[4 * i + 2] = a;\
-                                       ((TYPE *)(stream->buf))[4 * i + 3] = a;\
+                                       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++) {\
-                                       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];\
-                                       x = posmod(x, (TYPE)1);\
-                                       y = posmod(y, (TYPE)1);\
-                                       z = posmod(z, (TYPE)1);\
-                                       a = posmod(a, (TYPE)1);\
-                                       ((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;\
+                                       p = (TYPE *)(stream->buf) + i;\
+                                       *p = posmod(*p, (TYPE)1);\
                                }\
+                               n *= stream->chan_size;\
                        }\
-                       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));\
@@ -50,7 +39,6 @@ static int equal = 0;
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
@@ -70,9 +58,9 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
+       if (stream.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
+       else if (stream.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
diff --git a/src/blind-sinc-wave.c b/src/blind-sinc-wave.c
index 4ee2b52..f809c8e 100644
--- a/src/blind-sinc-wave.c
+++ b/src/blind-sinc-wave.c
@@ -5,7 +5,6 @@ USAGE("[-e] [theta0-stream]")
 
 static int equal = 0;
 
-
 #define PROCESS(TYPE, SUFFIX)\
        static void\
        process_##SUFFIX(struct stream *grad, struct stream *theta0)\
@@ -70,7 +69,6 @@ static int equal = 0;
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
@@ -96,9 +94,9 @@ main(int argc, char *argv[])
                        eprintf("theta0-stream must be of dimension 1x1\n");
        }
 
-       if (!strcmp(stream.pixfmt, "xyza"))
+       if (stream.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
+       else if (stream.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
diff --git a/src/blind-sine-wave.c b/src/blind-sine-wave.c
index 7e3cc5a..85bba2b 100644
--- a/src/blind-sine-wave.c
+++ b/src/blind-sine-wave.c
@@ -5,51 +5,34 @@ USAGE("[-e]")
 
 static int equal = 0;
 
-
 #define PROCESS(TYPE, SUFFIX)\
        static void\
        process_##SUFFIX(struct stream *stream)\
        {\
-               size_t i, n;\
-               TYPE x, y, z, a;\
+               size_t i, j, n;\
+               TYPE v, *p;\
                do {\
-                       n = stream->ptr / stream->pixel_size;\
                        if (equal) {\
+                               n = stream->ptr / stream->pixel_size;\
                                for (i = 0; i < n; i++) {\
-                                       a = ((TYPE *)(stream->buf))[4 * i + 3];\
-                                       a = posmod(a, (TYPE)2);\
-                                       a = a > 1 ? 2 - a : a;\
-                                       a = 1 - (cos(a * (TYPE)M_PI) + 1) / 2;\
-                                       ((TYPE *)(stream->buf))[4 * i + 0] = a;\
-                                       ((TYPE *)(stream->buf))[4 * i + 1] = a;\
-                                       ((TYPE *)(stream->buf))[4 * i + 2] = a;\
-                                       ((TYPE *)(stream->buf))[4 * i + 3] = a;\
+                                       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++) {\
-                                       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];\
-                                       x = posmod(x, (TYPE)1);\
-                                       y = posmod(y, (TYPE)1);\
-                                       z = posmod(z, (TYPE)1);\
-                                       a = posmod(a, (TYPE)1);\
-                                       x = x > 1 ? 2 - x : x;\
-                                       y = y > 1 ? 2 - y : y;\
-                                       z = z > 1 ? 2 - z : z;\
-                                       a = a > 1 ? 2 - a : a;\
-                                       x = 1 - (cos(x * (TYPE)M_PI) + 1) / 2;\
-                                       y = 1 - (cos(y * (TYPE)M_PI) + 1) / 2;\
-                                       z = 1 - (cos(z * (TYPE)M_PI) + 1) / 2;\
-                                       a = 1 - (cos(a * (TYPE)M_PI) + 1) / 2;\
-                                       ((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;\
+                                       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;\
                        }\
-                       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));\
@@ -60,7 +43,6 @@ static int equal = 0;
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
@@ -80,9 +62,9 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
+       if (stream.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
+       else if (stream.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
diff --git a/src/blind-spectrum.c b/src/blind-spectrum.c
index ceecf70..261d47c 100644
--- a/src/blind-spectrum.c
+++ b/src/blind-spectrum.c
@@ -6,7 +6,6 @@ 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)\
@@ -123,7 +122,6 @@ static size_t nz = 1;
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
diff --git a/src/blind-spiral-gradient.c b/src/blind-spiral-gradient.c
index 376bd7b..efb5655 100644
--- a/src/blind-spiral-gradient.c
+++ b/src/blind-spiral-gradient.c
@@ -12,7 +12,6 @@ static size_t height = 0;
 static int with_params;
 static int with_vector;
 
-
 #define PROCESS(TYPE, SUFFIX)\
        static void\
        process_##SUFFIX(struct stream *stream)\
@@ -116,7 +115,6 @@ static int with_vector;
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
diff --git a/src/blind-square-gradient.c b/src/blind-square-gradient.c
index 392a62f..25f4893 100644
--- a/src/blind-square-gradient.c
+++ b/src/blind-square-gradient.c
@@ -7,7 +7,6 @@ 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)\
@@ -63,7 +62,6 @@ static int with_multiplier;
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
diff --git a/src/blind-time-blur.c b/src/blind-time-blur.c
index 6d7a148..6144013 100644
--- a/src/blind-time-blur.c
+++ b/src/blind-time-blur.c
@@ -35,15 +35,15 @@ static int first = 1;
        } while (0)
 
 static void
-process_xyza(char *output, char *restrict cbuf, char *restrict abuf,
-            struct stream *colour, struct stream *alpha)
+process_lf(char *output, char *restrict cbuf, char *restrict abuf,
+          struct stream *colour, struct stream *alpha)
 {
        PROCESS(double);
 }
 
 static void
-process_xyzaf(char *output, char *restrict cbuf, char *restrict abuf,
-             struct stream *colour, struct stream *alpha)
+process_f(char *output, char *restrict cbuf, char *restrict abuf,
+         struct stream *colour, struct stream *alpha)
 {
        PROCESS(float);
 }
@@ -66,10 +66,10 @@ main(int argc, char *argv[])
        eopen_stream(&colour, NULL);
        eopen_stream(&alpha, argv[0]);
 
-       if (!strcmp(colour.pixfmt, "xyza"))
-               process = process_xyza;
-       else if (!strcmp(colour.pixfmt, "xyza f"))
-               process = process_xyzaf;
+       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);
 
diff --git a/src/blind-to-portable.c b/src/blind-to-portable.c
index 39e3d58..651c756 100644
--- a/src/blind-to-portable.c
+++ b/src/blind-to-portable.c
@@ -89,10 +89,10 @@ USAGE("[-s]")
        } while (0)
 
 static uint64_t conv_double(double host) {CONV(double, uint64_t, int64_t, 11, 
1023, 52);}
-static uint32_t conv_float (float  host) {CONV(float, uint32_t, int32_t, 8, 
127, 23);}
+static uint32_t conv_float (float  host) {CONV(float,  uint32_t, int32_t,  8,  
127, 23);}
 
-static void process_xyza (struct stream *stream, int strict) {PROCESS(double, 
uint64_t, 64);}
-static void process_xyzaf(struct stream *stream, int strict) {PROCESS(float, 
uint32_t, 32);}
+static void process_lf(struct stream *stream, int strict) {PROCESS(double, 
uint64_t, 64);}
+static void process_f (struct stream *stream, int strict) {PROCESS(float,  
uint32_t, 32);}
 
 int
 main(int argc, char *argv[])
@@ -113,10 +113,10 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_xyza;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_xyzaf;
+       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);
 
diff --git a/src/blind-to-text.c b/src/blind-to-text.c
index c8cf76e..7cee676 100644
--- a/src/blind-to-text.c
+++ b/src/blind-to-text.c
@@ -8,16 +8,13 @@ USAGE("")
 #define PROCESS(TYPE, CAST, FMT)\
        do {\
                size_t i;\
-               for (i = 0; i < n; i += stream->pixel_size)\
-                       printf("%"FMT" %"FMT" %"FMT" %"FMT"\n",\
-                              (CAST)(((TYPE *)(stream->buf + i))[0]),\
-                              (CAST)(((TYPE *)(stream->buf + i))[1]),\
-                              (CAST)(((TYPE *)(stream->buf + i))[2]),\
-                              (CAST)(((TYPE *)(stream->buf + i))[3]));\
+               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_xyza (struct stream *stream, size_t n) {PROCESS(double, 
double, ".25lf");}
-static void process_xyzaf(struct stream *stream, size_t n) {PROCESS(float,  
double, ".25lf");}
+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");}
 
 int
 main(int argc, char *argv[])
@@ -29,10 +26,10 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               process = process_xyza;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               process = process_xyzaf;
+       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);
 
diff --git a/src/blind-triangular-wave.c b/src/blind-triangular-wave.c
index 523e045..8e32d0f 100644
--- a/src/blind-triangular-wave.c
+++ b/src/blind-triangular-wave.c
@@ -6,54 +6,37 @@ USAGE("[-es]")
 static int equal = 0;
 static int spiral = 0;
 
-
 #define PROCESS(TYPE, SUFFIX)\
        static void\
        process_##SUFFIX(struct stream *stream)\
        {\
-               size_t i, n;\
-               TYPE x, y, z, a;\
+               size_t i, j, n;\
+               TYPE v, *p;\
                do {\
-                       n = stream->ptr / stream->pixel_size;\
                        if (equal) {\
+                               n = stream->ptr / stream->pixel_size;\
                                for (i = 0; i < n; i++) {\
-                                       a = ((TYPE *)(stream->buf))[4 * i + 3];\
-                                       a = posmod(a, (TYPE)2);\
-                                       a = a > 1 ? 2 - a : a;\
+                                       p = (TYPE *)(stream->buf) + i * 
stream->n_chan;\
+                                       v = posmod(*p, (TYPE)2);\
+                                       v = v > 1 ? 2 - v : v;\
                                        if (spiral)\
-                                               a = (a > (TYPE)0.5 ? 1 - a : a) 
* 2; \
-                                       ((TYPE *)(stream->buf))[4 * i + 0] = a;\
-                                       ((TYPE *)(stream->buf))[4 * i + 1] = a;\
-                                       ((TYPE *)(stream->buf))[4 * i + 2] = a;\
-                                       ((TYPE *)(stream->buf))[4 * i + 3] = a;\
+                                               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++) {\
-                                       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];\
-                                       x = posmod(x, (TYPE)2);\
-                                       y = posmod(y, (TYPE)2);\
-                                       z = posmod(z, (TYPE)2);\
-                                       a = posmod(a, (TYPE)2);\
-                                       x = x > 1 ? 2 - x : x;\
-                                       y = y > 1 ? 2 - y : y;\
-                                       z = z > 1 ? 2 - z : z;\
-                                       a = a > 1 ? 2 - a : a;\
-                                       if (spiral) {\
-                                               x = (x > (TYPE)0.5 ? 1 - x : x) 
* 2;\
-                                               y = (y > (TYPE)0.5 ? 1 - y : y) 
* 2;\
-                                               z = (z > (TYPE)0.5 ? 1 - z : z) 
* 2;\
-                                               a = (a > (TYPE)0.5 ? 1 - a : a) 
* 2;\
-                                       }\
-                                       ((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;\
+                                       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;\
                        }\
-                       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));\
@@ -64,7 +47,6 @@ static int spiral = 0;
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
@@ -87,9 +69,9 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
+       if (stream.encoding == DOUBLE)
                process = process_lf;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
+       else if (stream.encoding == FLOAT)
                process = process_f;
        else
                eprintf("pixel format %s is not supported, try xyza\n", 
stream.pixfmt);
diff --git a/src/blind-unpremultiply.c b/src/blind-unpremultiply.c
index d0639c8..18cc7b6 100644
--- a/src/blind-unpremultiply.c
+++ b/src/blind-unpremultiply.c
@@ -7,7 +7,6 @@ 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)\
@@ -38,7 +37,6 @@ static int skip_z = 0;
 PROCESS(double, lf)
 PROCESS(float, f)
 
-
 int
 main(int argc, char *argv[])
 {
diff --git a/src/stream.c b/src/stream.c
index 1cfb372..7ce32e2 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -95,12 +95,22 @@ enopen_stream(int status, struct stream *stream, const char 
*file)
 int
 set_pixel_size(struct stream *stream)
 {
-       if (!strcmp(stream->pixfmt, "xyza"))
-               stream->pixel_size = 4 * sizeof(double);
-       else if (!strcmp(stream->pixfmt, "xyza f"))
-               stream->pixel_size = 4 * sizeof(float);
-       else
+       if (!strcmp(stream->pixfmt, "xyza")) {
+               stream->n_chan = 4;
+               stream->chan_size = sizeof(double);
+               stream->space = CIEXYZ;
+               stream->alpha = UNPREMULTIPLIED;
+               stream->encoding = DOUBLE;
+       } else if (!strcmp(stream->pixfmt, "xyza f")) {
+               stream->n_chan = 4;
+               stream->chan_size = sizeof(float);
+               stream->space = CIEXYZ;
+               stream->alpha = UNPREMULTIPLIED;
+               stream->encoding = FLOAT;
+       } 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;
        stream->frame_size = stream->pixel_size * stream->height * 
stream->width;
@@ -212,31 +222,31 @@ encheck_compat(int status, const struct stream *a, const 
struct stream *b)
 const char *
 get_pixel_format(const char *specified, const char *current)
 {
-       const char *base = NULL;
-       int as_float = 0;
+       enum colour_space space;
+       enum encoding encoding;
 
        if (!strcmp(current, "xyza"))
-               base = "xyza";
+               space = CIEXYZ, encoding = DOUBLE;
        else if (!strcmp(current, "xyza f"))
-               base = "xyza", as_float = 1;
+               space = CIEXYZ, encoding = FLOAT;
        else
                return specified;
 
        if (!strcmp(specified, "xyza"))
-               base = "xyza";
+               space = CIEXYZ;
        else if (!strcmp(specified, "xyza f"))
                return "xyza f";
        else if (!strcmp(specified, "xyza !f"))
                return "xyza";
        else if (!strcmp(specified, "f"))
-               as_float = 1;
+               encoding = FLOAT;
        else if (!strcmp(specified, "!f"))
-               as_float = 0;
+               encoding = DOUBLE;
        else
                return specified;
 
-       if (!strcmp(base, "xyza"))
-               return as_float ? "xyza f" : "xyza";
+       if (space == CIEXYZ)
+               return encoding == FLOAT ? "xyza f" : "xyza";
        else
                return specified;
 }
diff --git a/src/stream.h b/src/stream.h
index 8733f43..f04918a 100644
--- a/src/stream.h
+++ b/src/stream.h
@@ -63,16 +63,31 @@ enum dimension {
        LENGTH = 4
 };
 
+enum colour_space {
+       CIEXYZ
+};
+
+enum alpha {
+       UNPREMULTIPLIED
+};
+
+enum encoding {
+       FLOAT,
+       DOUBLE
+};
+
 struct stream {
        size_t frames;
        size_t width;
        size_t height;
+       size_t n_chan;
+       size_t chan_size;
        size_t pixel_size;
        char pixfmt[32];
+       enum colour_space space;
+       enum alpha alpha;
+       enum encoding encoding;
        int fd;
-#if INT_MAX != LONG_MAX
-       int padding__;
-#endif
        size_t ptr;
        size_t xptr;
        char buf[BUFSIZ];

Reply via email to