commit 6b998b5ed066aeece1146fe245b35965319b3cbd
Author:     Mattias Andrée <[email protected]>
AuthorDate: Wed May 10 16:59:26 2017 +0200
Commit:     Mattias Andrée <[email protected]>
CommitDate: Wed May 10 16:59:26 2017 +0200

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

diff --git a/src/blind-arithm.c b/src/blind-arithm.c
index 4b540a6..77e691f 100644
--- a/src/blind-arithm.c
+++ b/src/blind-arithm.c
@@ -2,11 +2,8 @@
 #include "stream.h"
 #include "util.h"
 
-#include <fcntl.h>
 #include <math.h>
-#include <stdint.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-axyz] operation right-hand-stream")
 
diff --git a/src/blind-compress.c b/src/blind-compress.c
index 7669227..375055d 100644
--- a/src/blind-compress.c
+++ b/src/blind-compress.c
@@ -2,9 +2,6 @@
 #include "stream.h"
 #include "util.h"
 
-#include <string.h>
-#include <unistd.h>
-
 USAGE("")
 
 static size_t
@@ -33,7 +30,7 @@ main(int argc, char *argv[])
 {
        struct stream stream;
        char *buf[2];
-       size_t n, parts, part, off;
+       size_t parts, part, off;
        int i;
        size_t *cmp = NULL;
        size_t cmpsize = 0;
@@ -41,16 +38,15 @@ main(int argc, char *argv[])
        UNOFLAGS(argc);
 
        eopen_stream(&stream, NULL);
+       echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       echeck_frame_size(stream.width, stream.height, stream.pixel_size, 0, 
"<stdin>");
-       n = stream.width * stream.height * stream.pixel_size;
-       buf[0] = emalloc(n);
-       buf[1] = ecalloc(1, n);
+       buf[0] = emalloc(stream.frame_size);
+       buf[1] = ecalloc(1, stream.frame_size);
 
-       for (i = 0; eread_frame(&stream, buf[i], n); i ^= 1) {
-               parts = compare(buf[i], buf[i ^ 1], n, &cmp, &cmpsize);
+       for (i = 0; eread_frame(&stream, buf[i]); i ^= 1) {
+               parts = compare(buf[i], buf[i ^ 1], stream.frame_size, &cmp, 
&cmpsize);
                for (off = part = 0; part < parts; part += 2) {
                        off += cmp[part];
                        ewriteall(STDOUT_FILENO, cmp + part, 2 * 
sizeof(size_t), "<stdout>");
diff --git a/src/blind-concat.c b/src/blind-concat.c
index 53707e7..a323af8 100644
--- a/src/blind-concat.c
+++ b/src/blind-concat.c
@@ -6,11 +6,7 @@
 # include <sys/epoll.h>
 #endif
 #include <sys/mman.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <limits.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-o output-file [-j jobs]] first-stream ... last-stream")
 
@@ -104,7 +100,7 @@ concat_to_file_parallel(int argc, char *argv[], char 
*output_file, size_t jobs)
        struct stream *streams;
        size_t *ptrs;
        char head[STREAM_HEAD_MAX];
-       size_t ptr, frame_size, frames = 0, next = 0, j;
+       size_t ptr, frames = 0, next = 0, j;
        ssize_t headlen;
        int fd, i, n, pollfd;
 
@@ -127,12 +123,11 @@ concat_to_file_parallel(int argc, char *argv[], char 
*output_file, size_t jobs)
 
        SPRINTF_HEAD_ZN(head, frames, streams->width, streams->height, 
streams->pixfmt, &headlen);
 
-       echeck_frame_size(streams->width, streams->height, streams->pixel_size, 
0, output_file);
-       frame_size = streams->width * streams->height * streams->pixel_size;
+       echeck_dimensions(streams, WIDTH | HEIGHT, NULL);
        ptr = (size_t)headlen;
        for (i = 0; i < argc; i++) {
                ptrs[i] = ptr;
-               ptr += streams->frames * frame_size;
+               ptr += streams->frames * streams->frame_size;
        }
        if (ftruncate(fd, (off_t)ptr))
                eprintf("ftruncate %s:", output_file);
diff --git a/src/blind-crop.c b/src/blind-crop.c
index 1ad9a19..305f619 100644
--- a/src/blind-crop.c
+++ b/src/blind-crop.c
@@ -2,10 +2,7 @@
 #include "stream.h"
 #include "util.h"
 
-#include <fcntl.h>
-#include <inttypes.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-s | -S | -t] width height left top")
 
@@ -16,7 +13,7 @@ main(int argc, char *argv[])
        char *buf, *image, *p;
        size_t width = 0, height = 0, left = 0, top = 0;
        size_t right, right_start, bottom, bottom_start;
-       size_t off, yoff = 0, x, y, irown, orown, ptr, n, m;
+       size_t off, yoff = 0, x, y, irown, orown, ptr, m;
        int tile = 0, keepsize = 0, keepsize_inv = 0;
 
        ARGBEGIN {
@@ -56,11 +53,11 @@ main(int argc, char *argv[])
        }
        efflush(stdout, "<stdout>");
 
-       echeck_frame_size(stream.width, stream.height, stream.pixel_size, 0, 
stream.file);
-       n = stream.height * (irown = stream.width * stream.pixel_size);
-       buf = emalloc(n);
+       echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
+       irown = stream.row_size;
+       buf = emalloc(stream.frame_size);
        orown = width * stream.pixel_size;
-       m = (tile || keepsize || keepsize_inv) ? n : height * orown;
+       m = (tile || keepsize || keepsize_inv) ? stream.frame_size : height * 
orown;
        image = (keepsize || keepsize_inv) ? buf : emalloc(m);
 
        left *= stream.pixel_size;
@@ -73,7 +70,7 @@ main(int argc, char *argv[])
        bottom = stream.height - (bottom_start = top  + height);
        right  = irown         - (right_start  = left + orown);
 
-       while (eread_frame(&stream, buf, n)) {
+       while (eread_frame(&stream, buf)) {
                if (tile) {
                        for (ptr = y = 0; y < stream.height; y++) {
                                p = buf + ((y + yoff) % height + top) * irown;
diff --git a/src/blind-cut.c b/src/blind-cut.c
index 9f4357c..62ef98b 100644
--- a/src/blind-cut.c
+++ b/src/blind-cut.c
@@ -2,10 +2,7 @@
 #include "stream.h"
 #include "util.h"
 
-#include <limits.h>
-#include <stdint.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("start-point (end-point | 'end') file")
 
@@ -13,7 +10,7 @@ int
 main(int argc, char *argv[])
 {
        struct stream stream;
-       size_t frame_size, start = 0, end = 0, ptr, max;
+       size_t start = 0, end = 0, ptr, max;
        ssize_t r;
        char buf[BUFSIZ];
        int to_end = 0;
@@ -36,19 +33,16 @@ main(int argc, char *argv[])
        else if (end > stream.frames)
                eprintf("end point is after end of video\n");
        stream.frames = end - start;
+       echeck_dimensions(&stream, WIDTH | HEIGHT | LENGTH, NULL);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
-       echeck_frame_size(stream.width, stream.height, stream.pixel_size, 0, 
stream.file);
-       frame_size = stream.width * stream.height * stream.pixel_size;
-       if (stream.frames > (size_t)SSIZE_MAX / frame_size)
-               eprintf("%s: video is too large\n", stream.file);
 
        if (start >= end)
                eprintf("%s\n", start > end ?
                        "start point is after end point" :
                        "refusing to create video with zero frames");
-       end   = end   * frame_size + stream.headlen;
-       start = start * frame_size + stream.headlen;
+       end   = end   * stream.frame_size + stream.headlen;
+       start = start * stream.frame_size + stream.headlen;
 
        fadvise_sequential(stream.fd, start, end - start);
        for (ptr = start; ptr < end; ptr += (size_t)r) {
diff --git a/src/blind-decompress.c b/src/blind-decompress.c
index fd436f6..602fdac 100644
--- a/src/blind-decompress.c
+++ b/src/blind-decompress.c
@@ -3,7 +3,6 @@
 #include "util.h"
 
 #include <string.h>
-#include <unistd.h>
 
 USAGE("")
 
@@ -12,35 +11,34 @@ main(int argc, char *argv[])
 {
        struct stream stream;
        char *buf;
-       size_t n, m, fptr, sptr, same = 0, diff = 0;
+       size_t m, fptr, sptr, same = 0, diff = 0;
 
        UNOFLAGS(argc);
 
        eopen_stream(&stream, NULL);
+       echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       echeck_frame_size(stream.width, stream.height, stream.pixel_size, 0, 
"<stdin>");
-       n = stream.width * stream.height * stream.pixel_size;
-       buf = ecalloc(1, n);
+       buf = ecalloc(1, stream.frame_size);
 
        fptr = 0;
        do {
                sptr = 0;
        again:
                while (same) {
-                       m = MIN(same, n - fptr);
+                       m = MIN(same, stream.frame_size - fptr);
                        ewriteall(STDOUT_FILENO, buf + fptr, m, "<stdout>");
-                       fptr = (fptr + m) % n;
+                       fptr = (fptr + m) % stream.frame_size;
                        same -= m;
                }
 
                while (diff && sptr < stream.ptr) {
-                       m = MIN(diff, n - fptr);
+                       m = MIN(diff, stream.frame_size - fptr);
                        m = MIN(m, stream.ptr - sptr);
                        memcpy(buf + fptr, stream.buf + sptr, m);
                        ewriteall(STDOUT_FILENO, buf + fptr, m, "<stdout>");
-                       fptr = (fptr + m) % n;
+                       fptr = (fptr + m) % stream.frame_size;
                        diff -= m;
                        sptr += m;
                }
diff --git a/src/blind-dissolve.c b/src/blind-dissolve.c
index 1efe2a3..3bbe1b9 100644
--- a/src/blind-dissolve.c
+++ b/src/blind-dissolve.c
@@ -3,7 +3,6 @@
 #include "util.h"
 
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-r]")
 
diff --git a/src/blind-extend.c b/src/blind-extend.c
index 25b9e30..60536cf 100644
--- a/src/blind-extend.c
+++ b/src/blind-extend.c
@@ -2,10 +2,7 @@
 #include "stream.h"
 #include "util.h"
 
-#include <fcntl.h>
-#include <inttypes.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-l left] [-r right] [-a above] [-b below] [-t]")
 
@@ -14,7 +11,7 @@ main(int argc, char *argv[])
 {
        struct stream stream;
        char *buf, *image;
-       size_t n, m, imgw, imgh, rown;
+       size_t m, imgw, imgh, rown;
        size_t xoff, yoff, h, x, y;
        size_t left = 0, right = 0, top = 0, bottom = 0;
        int tile = 0;
@@ -44,9 +41,8 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 
-       echeck_frame_size(stream.width, stream.height, stream.pixel_size, 0, 
stream.file);
-       n = stream.height * stream.width * stream.pixel_size;
-       buf = emalloc(n);
+       echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
+       buf = emalloc(stream.frame_size);
 
        if (stream.width > SIZE_MAX - left)
                eprintf("<stdout>: output video is too wide\n");
@@ -60,7 +56,7 @@ main(int argc, char *argv[])
        if (imgh > SIZE_MAX - bottom)
                eprintf("<stdout>: output video is too tall\n");
        imgh += bottom;
-       echeck_frame_size(imgw, imgh, stream.pixel_size, "output", "<stdout>");
+       echeck_dimensions_custom(imgw, imgh, 0, stream.pixel_size, "output", 
"<stdout>");
        m = imgh * (imgw *= stream.pixel_size);
        image = tile ? emalloc(m) : ecalloc(1, m);
 
@@ -78,7 +74,7 @@ main(int argc, char *argv[])
        xoff = (rown          - left % rown)          % rown;
        yoff = (stream.height - top  % stream.height) % stream.height;
 
-       while (eread_frame(&stream, buf, n)) {
+       while (eread_frame(&stream, buf)) {
                if (!tile) {
                        for (y = 0; y < stream.height; y++)
                                memcpy(image + left + (y + top) * imgw, buf + y 
* rown, rown);
diff --git a/src/blind-flip.c b/src/blind-flip.c
index 71f30c4..e1b3b72 100644
--- a/src/blind-flip.c
+++ b/src/blind-flip.c
@@ -2,31 +2,27 @@
 #include "stream.h"
 #include "util.h"
 
-#include <string.h>
-#include <unistd.h>
-
 USAGE("")
 
 int
 main(int argc, char *argv[])
 {
        struct stream stream;
-       size_t n, rown, ptr;
+       size_t ptr;
        char *buf;
 
        UNOFLAGS(argc);
 
        eopen_stream(&stream, NULL);
+       echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
+       buf = emalloc(stream.frame_size);
 
-       echeck_frame_size(stream.width, stream.height, stream.pixel_size, 0, 
stream.file);
-       n = stream.height * (rown = stream.width * stream.pixel_size);
-       buf = emalloc(n);
-
-       while (eread_frame(&stream, buf, n))
-               for (ptr = n; ptr;)
-                       ewriteall(STDOUT_FILENO, buf + (ptr -= rown), rown, 
"<stdout>");
+       while (eread_frame(&stream, buf))
+               for (ptr = stream.frame_size; ptr;)
+                       ewriteall(STDOUT_FILENO, buf + (ptr -= stream.row_size),
+                                 stream.row_size, "<stdout>");
        /* ewriteall is faster than writev(3) and vmsplice(3) */
 
        free(buf);
diff --git a/src/blind-flop.c b/src/blind-flop.c
index c5826be..51f9ab5 100644
--- a/src/blind-flop.c
+++ b/src/blind-flop.c
@@ -2,10 +2,6 @@
 #include "stream.h"
 #include "util.h"
 
-#include <inttypes.h>
-#include <string.h>
-#include <unistd.h>
-
 USAGE("")
 
 static struct stream stream;
@@ -14,41 +10,40 @@ static size_t n, m, ps;
 
 #define PROCESS(TYPE)\
        do {\
-               size_t i, j, pst = ps / sizeof(TYPE);\
-               size_t nt = n / sizeof(TYPE);\
-               size_t mt = m / sizeof(TYPE);\
-               for (i = 0; i < pst; i++)\
-                       for (j = 0; j < nt; j += pst)\
-                               ((TYPE *)image)[mt - j + i] = ((TYPE *)buf)[i + 
j];\
+               size_t i, j;\
+               for (i = 0; i < ps; i++)\
+                       for (j = 0; j < n; j += ps)\
+                               ((TYPE *)image)[m - j + i] = ((TYPE *)buf)[i + 
j];\
        } while (0)
 
-static void process_double(void) {PROCESS(double);}
-static void process_float (void) {PROCESS(float);}
-static void process_char  (void) {PROCESS(char);}
+static void process_long(void) {PROCESS(long);}
+static void process_char(void) {PROCESS(char);}
 
 int
 main(int argc, char *argv[])
 {
-       void (*process)(void);
+       void (*process)(void) = process_char;
 
        UNOFLAGS(argc);
 
        eopen_stream(&stream, NULL);
+       echeck_dimensions(&stream, WIDTH, NULL);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
+       buf   = emalloc(stream.row_size);
+       image = emalloc(stream.row_size);
+
+       m = (n = stream.row_size) - (ps = stream.pixel_size);
+       if (!(stream.pixel_size % sizeof(long))) {
+               process = process_long;
+               m  /= sizeof(long);
+               n  /= sizeof(long);
+               ps /= sizeof(long);
+       }
 
-       echeck_frame_size(stream.width, 1, stream.pixel_size, 0, stream.file);
-       n = stream.width * (ps = stream.pixel_size);
-       buf   = emalloc(n);
-       image = emalloc(n);
-
-       process = !(ps % sizeof(double)) ? process_double :
-                 !(ps % sizeof(float))  ? process_float  : process_char;
-
-       m = n - ps;
-       while (eread_row(&stream, buf, n)) {
+       while (eread_row(&stream, buf)) {
                process();
-               ewriteall(STDOUT_FILENO, image, n, "<stdout>");
+               ewriteall(STDOUT_FILENO, image, stream.row_size, "<stdout>");
        }
 
        free(buf);
diff --git a/src/blind-from-image.c b/src/blind-from-image.c
index 040e8a9..babcc8c 100644
--- a/src/blind-from-image.c
+++ b/src/blind-from-image.c
@@ -3,16 +3,14 @@
 #include "util.h"
 
 #include <arpa/inet.h>
-#include <sys/wait.h>
 #include <inttypes.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-h] [-f | -p]")
 
 static char buf[BUFSIZ];
-static char width[3 * sizeof(size_t) + 1] = {0};
-static char height[3 * sizeof(size_t) + 1] = {0};
+static char width[INTSTRLEN(size_t) + 1] = {0};
+static char height[INTSTRLEN(size_t) + 1] = {0};
 static const char *conv_fail_msg = "convertion failed, if converting a 
farbfeld file, try -f";
 static size_t pixel_size;
 static double value_max;
@@ -143,7 +141,7 @@ pam_head(int fd, const char *fname)
                                else if (!strcmp(buf, "TUPLTYPE RGB_ALPHA"))
                                        with_colour = 1, with_alpha = 1;
                                else
-                                       eprintf("image uses an unsupported 
tuple type: %s\n", buf + sizeof("TUPLTYPE"));
+                                       eprintf("image uses an unsupported 
tuple type: %s\n", buf + STRLEN("TUPLTYPE "));
                        } else if (!strcmp(buf, "ENDHDR")) {
                                memmove(buf, p, ptr -= (size_t)(p - buf));
                                goto header_done;
diff --git a/src/blind-from-text.c b/src/blind-from-text.c
index 37a0799..a03adaf 100644
--- a/src/blind-from-text.c
+++ b/src/blind-from-text.c
@@ -2,10 +2,7 @@
 #include "stream.h"
 #include "util.h"
 
-#include <stdio.h>
-#include <stdint.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("")
 
diff --git a/src/blind-from-video.c b/src/blind-from-video.c
index 4c35e66..e81eb10 100644
--- a/src/blind-from-video.c
+++ b/src/blind-from-video.c
@@ -4,9 +4,6 @@
 
 #include <sys/mman.h>
 #include <sys/stat.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
 
 USAGE("[-F pixel-format] [-r frame-rate] [-w width -h height] [-dL] input-file 
output-file")
@@ -135,7 +132,7 @@ convert_segment_xyzaf(char *buf, size_t n, int fd, const 
char *file)
 static void
 convert(const char *infile, int outfd, const char *outfile, size_t width, 
size_t height, const char *frame_rate)
 {
-       char geometry[2 * 3 * sizeof(size_t) + 2], buf[BUFSIZ];
+       char geometry[2 * INTSTRLEN(size_t) + 2], buf[BUFSIZ];
        const char *cmd[13];
        int status, pipe_rw[2];
        size_t i = 0, n, ptr;
diff --git a/src/blind-gauss-blur.c b/src/blind-gauss-blur.c
index f4c99c0..f767994 100644
--- a/src/blind-gauss-blur.c
+++ b/src/blind-gauss-blur.c
@@ -2,12 +2,8 @@
 #include "stream.h"
 #include "util.h"
 
-#include <fcntl.h>
-#include <limits.h>
 #include <math.h>
-#include <stdint.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-j jobs] [-s spread | -s 'auto'] [-achvy] sd-stream")
 
@@ -29,15 +25,15 @@ static size_t spread = 0;
  * and smears it out to the other pixels.
  */
 
-#define BLUR_PIXEL_PROLOGUE(DIR)\
+#define BLUR_PIXEL_PROLOGUE(TYPE, DIR)\
        if (sig[i1][3] == 0)\
                goto no_blur_##DIR;\
        if (chroma || measure_y_only) {\
                k[0] = sig[i1][1] * sig[i1][3];\
                if (auto_spread)\
-                       spread = k[0] > 0 ? (size_t)(k[0] * 3 + 0.5) : 0;\
+                       spread = k[0] > 0 ? (size_t)(k[0] * 3 + (TYPE)0.5) : 0;\
                blur[2] = blur[0] = k[0] > 0;\
-               c[0] = k[0] *= k[0] * 2, c[0] = sqrt(c[0] * M_PI);\
+               c[0] = k[0] *= k[0] * 2, c[0] = sqrt(c[0] * (TYPE)M_PI);\
                k[0] = 1 / -k[0], c[0] = 1 / c[0];\
                if (chroma) {\
                        k[2] = k[0];\
@@ -54,10 +50,10 @@ static size_t spread = 0;
                        spread = 0;\
                for (i = 0; i < 3; i++) {\
                        k[i] = sig[i1][i] * sig[i1][3];\
-                       if (auto_spread && k[i] > 0 && spread < (size_t)(k[i] * 
3 + 0.5))\
-                               spread = (size_t)(k[i] * 3 + 0.5);\
+                       if (auto_spread && k[i] > 0 && spread < (size_t)(k[i] * 
3 + (TYPE)0.5))\
+                               spread = (size_t)(k[i] * 3 + (TYPE)0.5);\
                        blur[i] = k[i] > 0;\
-                       c[i] = k[i] *= k[i] * 2, c[i] = sqrt(c[i] * M_PI);\
+                       c[i] = k[i] *= k[i] * 2, c[i] = sqrt(c[i] * 
(TYPE)M_PI);\
                        k[i] = 1 / -k[i], c[i] = 1 / c[i];\
                }\
        }\
@@ -93,7 +89,7 @@ static size_t spread = 0;
                        for (LOOP) {\
                                d = (DISTANCE);\
                                d *= d;\
-                               m = c[i] * exp(d * k[i]);\
+                               m = c[i] * exp##SUFFIX(d * k[i]);\
                                img[i2][i] += clr[i1][i] * m;\
                                img[i2][3] += clr[i1][3] * m / blurred;\
                        }\
@@ -108,15 +104,15 @@ static size_t spread = 0;
        img[i1][2] = clr[i1][2];\
        img[i1][3] = clr[i1][3];
 
-#define BLUR(DIR, SETSTART, SETEND, START, LOOP, DISTANCE, SUFFIX)\
+#define BLUR(TYPE, DIR, SETSTART, SETEND, START, LOOP, DISTANCE, SUFFIX)\
        do {\
-               memset(img, 0, cn);\
+               memset(img, 0, colour->frame_size);\
                start = 0, end = colour->height;\
                is_master = efork_jobs(&start, &end, jobs, &children);\
                i1 = start * colour->width;\
                for (y1 = start; y1 < end; y1++) {\
                        for (x1 = 0; x1 < colour->width; x1++, i1++) {\
-                               BLUR_PIXEL_PROLOGUE(DIR);\
+                               BLUR_PIXEL_PROLOGUE(TYPE, DIR);\
                                if (spread) {\
                                        SETSTART;\
                                        SETEND;\
@@ -168,8 +164,8 @@ static size_t spread = 0;
                                i1 = start * colour->width;\
                                for (y1 = start; y1 < end; y1++) {\
                                        for (x1 = 0; x1 < colour->width; x1++, 
i1++) {\
-                                               clr[i1][0] = clr[i1][0] / 
D65_XYZ_X - clr[i1][1];\
-                                               clr[i1][2] = clr[i1][2] / 
D65_XYZ_Z - clr[i1][1];\
+                                               clr[i1][0] = clr[i1][0] / 
(TYPE)D65_XYZ_X - clr[i1][1];\
+                                               clr[i1][2] = clr[i1][2] / 
(TYPE)D65_XYZ_Z - clr[i1][1];\
                                                /*
                                                 * Explaination:
                                                 *   Y is the luma and ((X / Xn 
- Y / Yn), (Z / Zn - Y / Yn))
@@ -225,7 +221,7 @@ static size_t spread = 0;
                \
                /* blur */\
                if (horizontal)\
-                       BLUR(horizontal,\
+                       BLUR(TYPE, horizontal,\
                             x2start = spread > x1 ? 0 : x1 - spread,\
                             x2end = spread + 1 > colour->width - x1 ? 
colour->width : x1 + spread + 1,\
                             i2 = y1 * colour->width + x2start,\
@@ -233,9 +229,9 @@ static size_t spread = 0;
                             (ssize_t)x1 - (ssize_t)x2,\
                             SUFFIX);\
                if (horizontal && vertical)\
-                       memcpy(clr, img, cn);\
+                       memcpy(clr, img, colour->frame_size);\
                if (vertical)\
-                       BLUR(vertical,\
+                       BLUR(TYPE, vertical,\
                             y2start = spread > y1 ? 0 : y1 - spread,\
                             y2end = spread + 1 > colour->height - y1 ? 
colour->height : y1 + spread + 1,\
                             i2 = y2start * colour->width + x1,\
@@ -251,8 +247,8 @@ static size_t spread = 0;
                        i1 = start * colour->width;\
                        for (y1 = start; y1 < end; y1++) {\
                                for (x1 = 0; x1 < colour->width; x1++, i1++) {\
-                                       img[i1][0] = (img[i1][0] + img[i1][1]) 
* D65_XYZ_X;\
-                                       img[i1][2] = (img[i1][2] + img[i1][1]) 
* D65_XYZ_Z;\
+                                       img[i1][0] = (img[i1][0] + img[i1][1]) 
* (TYPE)D65_XYZ_X;\
+                                       img[i1][2] = (img[i1][2] + img[i1][1]) 
* (TYPE)D65_XYZ_Z;\
                                }\
                        }\
                }\
@@ -280,19 +276,18 @@ static size_t spread = 0;
                ejoin_jobs(is_master, children);\
                \
                (void) sigma;\
-               (void) sn;\
        } while (0)
 
 static void
 process_xyza(char *restrict output, char *restrict cbuf, char *restrict sbuf,
-            struct stream *colour, struct stream *sigma, size_t cn, size_t sn)
+            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, size_t cn, size_t sn)
+            struct stream *colour, struct stream *sigma)
 {
        PROCESS(float, f);
 }
@@ -303,7 +298,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, size_t cn, 
size_t sn);
+                       struct stream *colour, struct stream *sigma);
 
        ARGBEGIN {
        case 'a':
diff --git a/src/blind-invert-luma.c b/src/blind-invert-luma.c
index c169fd6..cedfc2e 100644
--- a/src/blind-invert-luma.c
+++ b/src/blind-invert-luma.c
@@ -2,10 +2,7 @@
 #include "stream.h"
 #include "util.h"
 
-#include <fcntl.h>
-#include <stdint.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-iw] mask-stream")
 
diff --git a/src/blind-next-frame.c b/src/blind-next-frame.c
index b155b2b..e6e7f4b 100644
--- a/src/blind-next-frame.c
+++ b/src/blind-next-frame.c
@@ -2,9 +2,7 @@
 #include "stream.h"
 #include "util.h"
 
-#include <inttypes.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-f frames] width height pixel-format ...")
 
diff --git a/src/blind-read-head.c b/src/blind-read-head.c
index 00b6d61..cc5ea81 100644
--- a/src/blind-read-head.c
+++ b/src/blind-read-head.c
@@ -3,7 +3,6 @@
 #include "util.h"
 
 #include <ctype.h>
-#include <unistd.h>
 
 USAGE("")
 
@@ -27,7 +26,7 @@ main(int argc, char *argv[])
                goto bad_format;
 
        p = buf;
-       for (i = 0; i < 5; i++)
+       for (i = 0; i < ELEMENTSOF(magic); i++)
                if (!eread(STDIN_FILENO, &b, 1, "<stdin>") || b != magic[i])
                        goto bad_format;
 
diff --git a/src/blind-repeat.c b/src/blind-repeat.c
index 937536b..6e2b169 100644
--- a/src/blind-repeat.c
+++ b/src/blind-repeat.c
@@ -2,10 +2,7 @@
 #include "stream.h"
 #include "util.h"
 
-#include <errno.h>
-#include <stdint.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("(count | 'inf') file")
 
diff --git a/src/blind-reverse.c b/src/blind-reverse.c
index 69013bb..7d3e504 100644
--- a/src/blind-reverse.c
+++ b/src/blind-reverse.c
@@ -2,21 +2,18 @@
 #include "stream.h"
 #include "util.h"
 
-#include <limits.h>
-#include <unistd.h>
-
 USAGE("[-i] file")
 
 static void
-to_stdout(struct stream *stream, size_t frame_size)
+to_stdout(struct stream *stream)
 {
        size_t ptr, end, n;
        char buf[BUFSIZ];
        ssize_t r;
 
        while (stream->frames--) {
-               ptr = stream->frames * frame_size + stream->headlen;
-               end = ptr + frame_size;
+               ptr = stream->frames * stream->frame_size + stream->headlen;
+               end = ptr + stream->frame_size;
                while (ptr < end) {
                        if (!(r = epread(stream->fd, buf, MIN(sizeof(buf), end 
- ptr), ptr, stream->file)))
                                eprintf("%s: file is shorter than expected\n", 
stream->file);
@@ -35,39 +32,39 @@ elseek_set(int fd, off_t offset, const char *fname)
 }
 
 static void
-epread_frame(struct stream *stream, char *buf, off_t off, size_t n)
+epread_frame(struct stream *stream, char *buf, off_t off)
 {
        stream->ptr = stream->xptr = 0;
        elseek_set(stream->fd, off, stream->file);
-       eread_frame(stream, buf, n);
+       eread_frame(stream, buf);
 }
 
 static void
-epwrite_frame(struct stream *stream, char *buf, off_t off, size_t n)
+epwrite_frame(struct stream *stream, char *buf, off_t off)
 {
        elseek_set(stream->fd, off, stream->file);
-       ewriteall(stream->fd, buf, n, stream->file);
+       ewriteall(stream->fd, buf, stream->frame_size, stream->file);
 }
 
 static void
-in_place(struct stream *stream, size_t frame_size)
+in_place(struct stream *stream)
 {
        size_t f, fm = stream->frames - 1;
        off_t pa, pb;
        char *bufa, *bufb;
 
-       bufa = emalloc(frame_size);
-       bufb = emalloc(frame_size);
+       bufa = emalloc(stream->frame_size);
+       bufb = emalloc(stream->frame_size);
 
        for (f = 0; f < stream->frames >> 1; f++) {
-               pa = f        * frame_size + stream->headlen;
-               pb = (fm - f) * frame_size + stream->headlen;
+               pa = f        * stream->frame_size + stream->headlen;
+               pb = (fm - f) * stream->frame_size + stream->headlen;
 
-               epread_frame(stream, bufa, pa, frame_size);
-               epread_frame(stream, bufb, pb, frame_size);
+               epread_frame(stream, bufa, pa);
+               epread_frame(stream, bufb, pb);
 
-               epwrite_frame(stream, bufa, pb, frame_size);
-               epwrite_frame(stream, bufb, pa, frame_size);
+               epwrite_frame(stream, bufa, pb);
+               epwrite_frame(stream, bufb, pa);
        }
 
        free(bufa);
@@ -78,7 +75,6 @@ int
 main(int argc, char *argv[])
 {
        struct stream stream;
-       size_t frame_size;
        int inplace = 0;
 
        ARGBEGIN {
@@ -99,17 +95,15 @@ main(int argc, char *argv[])
                fprint_stream_head(stdout, &stream);
                efflush(stdout, "<stdout>");
        }
-       echeck_frame_size(stream.width, stream.height, stream.pixel_size, 0, 
stream.file);
-       frame_size = stream.width * stream.height * stream.pixel_size;
-       if (stream.frames > (size_t)SSIZE_MAX / frame_size ||
-           stream.frames * frame_size > (size_t)SSIZE_MAX - stream.headlen)
+       echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
+       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
 
-       (inplace ? in_place : to_stdout)(&stream, frame_size);
+       (inplace ? in_place : to_stdout)(&stream);
        close(stream.fd);
        return 0;
 }
diff --git a/src/blind-rewrite-head.c b/src/blind-rewrite-head.c
index 5e25645..894e431 100644
--- a/src/blind-rewrite-head.c
+++ b/src/blind-rewrite-head.c
@@ -4,11 +4,7 @@
 
 #include <sys/mman.h>
 #include <sys/stat.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <inttypes.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-h] file [(frames | 'auto') [(width | 'same') (height | 'same') 
[format | 'same']]]")
 
@@ -17,20 +13,19 @@ rewrite(struct stream *stream, int frames_auto)
 {
        char head[STREAM_HEAD_MAX];
        ssize_t headlen;
-       size_t frame_size, frame_count, length;
+       size_t frame_count, length;
        struct stat st;
        char *data;
 
-       echeck_frame_size(stream->width, stream->height, stream->pixel_size, 0, 
stream->file);
-       frame_size = stream->width * stream->height * stream->pixel_size;
+       echeck_dimensions(stream, WIDTH | HEIGHT, NULL);
 
        if (fstat(stream->fd, &st))
                eprintf("fstat %s:", stream->file);
        if (!S_ISREG(st.st_mode))
                eprintf("%s: not a regular file\n", stream->file);
 
-       frame_count = (size_t)(st.st_size) / frame_size;
-       if (frame_count * frame_size != (size_t)(st.st_size) - stream->headlen)
+       frame_count = (size_t)(st.st_size) / stream->frame_size;
+       if (frame_count * stream->frame_size != (size_t)(st.st_size) - 
stream->headlen)
                eprintf("%s: given the select width and height, "
                        "the file has an incomplete frame\n", stream->file);
        if (frames_auto)
@@ -40,7 +35,7 @@ rewrite(struct stream *stream, int frames_auto)
 
        SPRINTF_HEAD_ZN(head, stream->frames, stream->width, stream->height, 
stream->pixfmt, &headlen);
 
-       length = stream->frames * frame_size;
+       length = stream->frames * stream->frame_size;
        if (length > (size_t)SSIZE_MAX || (size_t)headlen > (size_t)SSIZE_MAX - 
length)
                eprintf("%s: video is too long\n", stream->file);
 
diff --git a/src/blind-set-alpha.c b/src/blind-set-alpha.c
index 40f1a9e..72222f6 100644
--- a/src/blind-set-alpha.c
+++ b/src/blind-set-alpha.c
@@ -2,10 +2,7 @@
 #include "stream.h"
 #include "util.h"
 
-#include <fcntl.h>
-#include <stdint.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-i] alpha-stream")
 
diff --git a/src/blind-set-luma.c b/src/blind-set-luma.c
index 2c2b885..bc569e9 100644
--- a/src/blind-set-luma.c
+++ b/src/blind-set-luma.c
@@ -2,10 +2,7 @@
 #include "stream.h"
 #include "util.h"
 
-#include <fcntl.h>
-#include <stdint.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("luma-stream")
 
diff --git a/src/blind-set-saturation.c b/src/blind-set-saturation.c
index 472863f..626fc37 100644
--- a/src/blind-set-saturation.c
+++ b/src/blind-set-saturation.c
@@ -2,10 +2,7 @@
 #include "stream.h"
 #include "util.h"
 
-#include <fcntl.h>
-#include <stdint.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-w] saturation-stream")
 
diff --git a/src/blind-single-colour.c b/src/blind-single-colour.c
index f7a1afe..d367a37 100644
--- a/src/blind-single-colour.c
+++ b/src/blind-single-colour.c
@@ -2,9 +2,7 @@
 #include "stream.h"
 #include "util.h"
 
-#include <inttypes.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-f frames | -f 'inf'] [-F pixel-format] -w width -h height (X Y Z | Y) 
[alpha]")
 
diff --git a/src/blind-skip-pattern.c b/src/blind-skip-pattern.c
index 914bed4..e8eee0b 100644
--- a/src/blind-skip-pattern.c
+++ b/src/blind-skip-pattern.c
@@ -2,20 +2,18 @@
 #include "stream.h"
 #include "util.h"
 
-#include <inttypes.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("(skipped-frames | +included-frames) ...")
 
 static int
-process_frame(struct stream *stream, int include, size_t rown)
+process_frame(struct stream *stream, int include)
 {
        size_t h, n, m;
        int anything = 0;
 
        for (h = stream->height; h; h--) {
-               for (n = rown; n; n -= m, anything = 1) {
+               for (n = stream->row_size; n; n -= m, anything = 1) {
                        if (!stream->ptr && !eread_stream(stream, n))
                                goto done;
                        m = MIN(stream->ptr, n);
@@ -37,7 +35,7 @@ main(int argc, char *argv[])
 {
        struct stream stream;
        int i, include;
-       size_t f, n, rown, total = 0;
+       size_t f, n, total = 0;
        char *includes;
        size_t *ns;
 
@@ -64,16 +62,15 @@ main(int argc, char *argv[])
                        total += (size_t)include;
        }
 
-       echeck_frame_size(stream.width, 1, stream.pixel_size, 0, stream.file);
-       rown = stream.width * stream.pixel_size;
        stream.frames = total;
+       echeck_dimensions(&stream, WIDTH, NULL);
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
        for (i = 0;; i = (i + 1) % argc) {
                include = (int)includes[i];
                for (n = ns[i]; n--;)
-                       if (!process_frame(&stream, include, rown))
+                       if (!process_frame(&stream, include))
                                goto done;
        }
 
diff --git a/src/blind-split.c b/src/blind-split.c
index e92fced..f6949f6 100644
--- a/src/blind-split.c
+++ b/src/blind-split.c
@@ -3,11 +3,7 @@
 #include "util.h"
 
 #include <alloca.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <limits.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-L] (file (end-point | 'end')) ...")
 
@@ -15,7 +11,7 @@ int
 main(int argc, char *argv[])
 {
        struct stream stream;
-       size_t *ends, i, parts, ptr, end, frame_size, n;
+       size_t *ends, i, parts, ptr, end, n;
        char *to_end;
        FILE *fp;
        int fd, unknown_length = 0;
@@ -32,10 +28,7 @@ main(int argc, char *argv[])
                usage();
 
        eopen_stream(&stream, NULL);
-       echeck_frame_size(stream.width, stream.height, stream.pixel_size, 0, 
stream.file);
-       frame_size = stream.width * stream.height * stream.pixel_size;
-       if (stream.frames > (size_t)SSIZE_MAX / frame_size)
-               eprintf("%s: video is too large\n", stream.file);
+       echeck_dimensions(&stream, WIDTH | HEIGHT | LENGTH, NULL);
 
        parts = (size_t)argc / 2;
        ends = alloca(parts * sizeof(*ends));
@@ -66,7 +59,7 @@ main(int argc, char *argv[])
                fprint_stream_head(fp, &stream);
                efflush(fp, argv[i * 2]);
 
-               for (end = to_end[i] ? SIZE_MAX : ends[i] * frame_size; ptr < 
end; ptr += n) {
+               for (end = to_end[i] ? SIZE_MAX : ends[i] * stream.frame_size; 
ptr < end; ptr += n) {
                        n = end - ptr;
                        if (stream.ptr) {
                                n = MIN(stream.ptr, n);
@@ -75,7 +68,7 @@ main(int argc, char *argv[])
                        } else if ((n = eread_stream(&stream, n))) {
                                ewriteall(fd, stream.buf, n, argv[i * 2]);
                                stream.ptr = 0;
-                       } else if (ptr % frame_size) {
+                       } else if (ptr % stream.frame_size) {
                                eprintf("%s: incomplete frame\n", stream.file);
                        } else if (!unknown_length || !to_end[i]) {
                                eprintf("%s: file is shorter than expected\n", 
stream.file);
diff --git a/src/blind-stack.c b/src/blind-stack.c
index 72233a2..4591154 100644
--- a/src/blind-stack.c
+++ b/src/blind-stack.c
@@ -2,10 +2,7 @@
 #include "stream.h"
 #include "util.h"
 
-#include <fcntl.h>
-#include <inttypes.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-b] bottom-stream ... top-stream")
 
diff --git a/src/blind-time-blur.c b/src/blind-time-blur.c
index 702b280..5062de4 100644
--- a/src/blind-time-blur.c
+++ b/src/blind-time-blur.c
@@ -15,11 +15,11 @@ static int first = 1;
                pixel_t *restrict clr = (pixel_t *)cbuf;\
                pixel_t *restrict alf = (pixel_t *)abuf;\
                pixel_t *img = (pixel_t *)output;\
-               size_t i, n = cn / sizeof(pixel_t);\
+               size_t i, n = colour->frame_size / sizeof(pixel_t);\
                TYPE a1, a2;\
                \
                if (first) {\
-                       memcpy(output, cbuf, cn);\
+                       memcpy(output, cbuf, colour->frame_size);\
                        first = 0;\
                        return;\
                }\
@@ -36,19 +36,18 @@ static int first = 1;
                \
                (void) colour;\
                (void) alpha;\
-               (void) an;\
        } while (0)
 
 static void
 process_xyza(char *output, char *restrict cbuf, char *restrict abuf,
-            struct stream *colour, struct stream *alpha, size_t cn, size_t an)
+            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, size_t cn, size_t an)
+             struct stream *colour, struct stream *alpha)
 {
        PROCESS(float);
 }
@@ -58,7 +57,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, size_t cn, 
size_t an);
+                       struct stream *colour, struct stream *alpha);
 
        ARGBEGIN {
        default:
@@ -79,7 +78,6 @@ main(int argc, char *argv[])
                eprintf("pixel format %s is not supported, try xyza\n", 
colour.pixfmt);
 
        echeck_compat(&colour, &alpha);
-
        fprint_stream_head(stdout, &colour);
        efflush(stdout, "<stdout>");
        process_each_frame_two_streams(&colour, &alpha, STDOUT_FILENO, 
"<stdout>", process);
diff --git a/src/blind-to-image.c b/src/blind-to-image.c
index c7cf37d..f13ae1c 100644
--- a/src/blind-to-image.c
+++ b/src/blind-to-image.c
@@ -3,11 +3,7 @@
 #include "util.h"
 
 #include <arpa/inet.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-d depth | -f]")
 
diff --git a/src/blind-to-text.c b/src/blind-to-text.c
index 59ab8c3..ed95f08 100644
--- a/src/blind-to-text.c
+++ b/src/blind-to-text.c
@@ -2,9 +2,7 @@
 #include "stream.h"
 #include "util.h"
 
-#include <stdint.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("")
 
diff --git a/src/blind-to-video.c b/src/blind-to-video.c
index a98d719..5d25789 100644
--- a/src/blind-to-video.c
+++ b/src/blind-to-video.c
@@ -66,7 +66,7 @@ int
 main(int argc, char *argv[])
 {
        struct stream stream;
-       char geometry[2 * 3 * sizeof(size_t) + 2];
+       char geometry[2 * INTSTRLEN(size_t) + 2];
        char *frame_rate;
        const char **cmd;
        size_t n = 0;
diff --git a/src/blind-translate.c b/src/blind-translate.c
index d8f44e2..6b0ebd8 100644
--- a/src/blind-translate.c
+++ b/src/blind-translate.c
@@ -2,10 +2,7 @@
 #include "stream.h"
 #include "util.h"
 
-#include <inttypes.h>
-#include <math.h>
 #include <string.h>
-#include <unistd.h>
 
 USAGE("[-wp] translation-stream")
 
@@ -29,25 +26,24 @@ next_pixel(struct stream *stream, size_t *ptr)
 }
 
 static int
-process_frame(struct stream *stream, char *buf, size_t n,
-             size_t above, size_t below, size_t left, size_t right)
+process_frame(struct stream *stream, char *buf, size_t above, size_t below, 
size_t left, size_t right)
 {
 #define ZEROES(N) ewritezeroes(STDOUT_FILENO, zeroes, sizeof(zeroes), N, 
"<stdout>")
 
-       size_t i, w = n - left - right;
+       size_t i, w = stream->row_size - left - right;
        int first = 1;
 
-       if (!eread_row(stream, buf, n))
+       if (!eread_row(stream, buf))
                return 0;
 
        for (i = 0; i < above; i++)
-               ZEROES(n);
+               ZEROES(stream->row_size);
        for (i = 0; i < below; i++, first = 0)
-               if (!first && !eread_row(stream, buf, n))
+               if (!first && !eread_row(stream, buf))
                        goto eof;
 
        for (i = above + below; i < stream->height; i++, first = 0) {
-               if (!first && !eread_row(stream, buf, n))
+               if (!first && !eread_row(stream, buf))
                        goto eof;
                ZEROES((size_t)left);
                ewriteall(STDOUT_FILENO, buf + right, w, "<stdout>");
@@ -55,9 +51,9 @@ process_frame(struct stream *stream, char *buf, size_t n,
        }
 
        for (i = 0; i < below; i++)
-               ZEROES(n);
+               ZEROES(stream->row_size);
        for (i = 0; i < above; i++, first = 0)
-               if (!first && !eread_row(stream, buf, n))
+               if (!first && !eread_row(stream, buf))
                        goto eof;
 
        return 1;
@@ -70,16 +66,15 @@ static void
 process(struct stream *stream, struct stream *trstream)
 {
        char *buf;
-       size_t n, p = 0;
+       size_t p = 0;
        double *trans, tmp;
        ssize_t trx = 0, try = 0;
        size_t above = 0, below = 0, left = 0, right = 0;
 
        memset(zeroes, 0, sizeof(zeroes));
 
-       echeck_frame_size(stream->width, 1, stream->pixel_size, 0, 
stream->file);
-       n = stream->width * stream->pixel_size;
-       buf = emalloc(n);
+       echeck_dimensions(stream, WIDTH, NULL);
+       buf = emalloc(stream->row_size);
 
        do {
                if ((trans = next_pixel(trstream, &p))) {
@@ -93,10 +88,10 @@ process(struct stream *stream, struct stream *trstream)
 
                        above = MIN(above, stream->height);
                        below = MIN(below, stream->height);
-                       left  = MIN(left,  n);
-                       right = MIN(right, n);
+                       left  = MIN(left,  stream->row_size);
+                       right = MIN(right, stream->row_size);
                }
-       } while (process_frame(stream, buf, n, above, below, left, right));
+       } while (process_frame(stream, buf, above, below, left, right));
 
        free(buf);
 }
@@ -105,16 +100,15 @@ static void
 process_wrap(struct stream *stream, struct stream *trstream)
 {
        char *buf, *row;
-       size_t n, rown, p = 0;
+       size_t p = 0;
        double *trans, tmp;
        ssize_t trx = 0, try = 0, py;
        size_t off = 0, y;
 
-       echeck_frame_size(stream->width, stream->height, stream->pixel_size, 0, 
"<stdin>");
-       n = stream->height * (rown = stream->width * stream->pixel_size);
-       buf = emalloc(n);
+       echeck_dimensions(stream, WIDTH | HEIGHT, NULL);
+       buf = emalloc(stream->frame_size);
 
-       while (eread_frame(stream, buf, n)) {
+       while (eread_frame(stream, buf)) {
                if ((trans = next_pixel(trstream, &p))) {
                        trx = (ssize_t)(tmp = round(invtrans ? -trans[0] : 
trans[0]));
                        try = (ssize_t)(tmp = round(invtrans ? -trans[1] : 
trans[1]));
@@ -129,8 +123,8 @@ process_wrap(struct stream *stream, struct stream *trstream)
                        py = ((ssize_t)y - try) % (ssize_t)stream->height;
                        if (py < 0)
                                py += (ssize_t)stream->height;
-                       row = buf + (size_t)py * rown;
-                       ewriteall(STDOUT_FILENO, row + off, rown - off, 
"<stdout>");
+                       row = buf + (size_t)py * stream->row_size;
+                       ewriteall(STDOUT_FILENO, row + off, stream->row_size - 
off, "<stdout>");
                        ewriteall(STDOUT_FILENO, row, off, "<stdout>");
                }
        }
diff --git a/src/blind-transpose.c b/src/blind-transpose.c
index cc7e7d3..750de02 100644
--- a/src/blind-transpose.c
+++ b/src/blind-transpose.c
@@ -2,11 +2,6 @@
 #include "stream.h"
 #include "util.h"
 
-#include <fcntl.h>
-#include <inttypes.h>
-#include <string.h>
-#include <unistd.h>
-
 USAGE("")
 
 static size_t srcw, srch, srcwps, srchps, ps;
@@ -23,38 +18,33 @@ static size_t srcw, srch, srcwps, srchps, ps;
                }\
        } while (0)
 
-static void process_double(char *row, char *col) {PROCESS(double);}
-static void process_float (char *row, char *col) {PROCESS(float);}
-static void process_char  (char *row, char *col) {PROCESS(char);}
+static void process_long(char *row, char *col) {PROCESS(long);}
+static void process_char(char *row, char *col) {PROCESS(char);}
 
 int
 main(int argc, char *argv[])
 {
        struct stream stream;
        char *buf, *image;
-       size_t n, y;
+       size_t y;
        void (*process)(char *row, char *col);
 
        UNOFLAGS(argc);
 
        eopen_stream(&stream, NULL);
-       srch = stream.height;
-       stream.height = srcw = stream.width;
-       stream.width = srch;
+       echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
+       srch = stream.height, srchps = stream.col_size;
+       srcw = stream.width,  srcwps = stream.row_size;
+       stream.height = srcw;
+       stream.width  = srch;
        fprint_stream_head(stdout, &stream);
        efflush(stdout, "<stdout>");
 
-       echeck_frame_size(stream.width, stream.height, stream.pixel_size, 0, 
stream.file);
-       n = stream.height * stream.width * (ps = stream.pixel_size);
-       srchps = srch * ps;
-       srcwps = srcw * ps;
-       buf   = emalloc(n);
+       buf   = emalloc(stream.frame_size);
        image = emalloc(srchps);
 
-       process = !(ps % sizeof(double)) ? process_double :
-                 !(ps % sizeof(float))  ? process_float  : process_char;
-
-       while (eread_frame(&stream, buf, n)) {
+       process = ps % sizeof(long) ? process_char : process_long;
+       while (eread_frame(&stream, buf)) {
                for (y = 0; y < srcwps; y += ps) {
                        process(image, buf + y);
                        ewriteall(STDOUT_FILENO, image, srchps, "<stdout>");
diff --git a/src/stream.c b/src/stream.c
index 46edfa8..259b967 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -110,6 +110,9 @@ set_pixel_size(struct stream *stream)
                stream->pixel_size = 4 * sizeof(float);
        else
                return -1;
+       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;
        return 0;
 }
 
@@ -152,27 +155,49 @@ eninf_check_fd(int status, int fd, const char *file)
 }
 
 
-int
-check_frame_size(size_t width, size_t height, size_t pixel_size)
-{
-       if (!height)
-               return !width || !pixel_size || !(width > SIZE_MAX / 
pixel_size);
-       if (!width)
-               return !height || !pixel_size || !(height > SIZE_MAX / 
pixel_size);
-       if (!pixel_size)
-               return 1;
-       if (width > SIZE_MAX / height)
-               return 0;
-       return !(width * height > SIZE_MAX / pixel_size);
-}
-
 void
-encheck_frame_size(int status, size_t width, size_t height, size_t pixel_size, 
const char *prefix, const char *fname)
+encheck_dimensions(int status, const struct stream *stream, enum dimension 
dimensions, const char *prefix)
 {
-       if (!check_frame_size(width, height, pixel_size))
-               enprintf(status, "%s: %s%svideo frame is too %s\n",
-                        fname, prefix ? prefix : "", (prefix && *prefix) ? " " 
: "",
-                        width <= 1 ? "tall" : height <= 1 ? "wide" : "large");
+       size_t n;
+
+       if (!stream->pixel_size)
+               enprintf(status, "%s: %s%svideo frame doesn't have a pixel 
size\n",
+                        stream->file, prefix ? prefix : "",
+                        (prefix && *prefix) ? " " : "");
+
+       n = SIZE_MAX / stream->pixel_size;
+
+       if ((dimensions & WIDTH) && stream->width > n)
+               enprintf(status, "%s: %s%svideo frame is too wide\n",
+                        stream->file, prefix ? prefix : "",
+                        (prefix && *prefix) ? " " : "");
+
+       if ((dimensions & HEIGHT) && stream->height > n)
+               enprintf(status, "%s: %s%svideo frame is too wide\n",
+                        stream->file, prefix ? prefix : "",
+                        (prefix && *prefix) ? " " : "");
+
+       if (!stream->width || !stream->height)
+               return;
+
+       if ((dimensions & (WIDTH | HEIGHT)) == (WIDTH | HEIGHT)) {
+               if (stream->width > n / stream->height)
+                       enprintf(status, "%s: %s%svideo frame is too large\n",
+                                stream->file, prefix ? prefix : "",
+                                (prefix && *prefix) ? " " : "");
+       }
+
+       if (!(dimensions & LENGTH))
+               return;
+       if (dimensions & WIDTH)
+               n /= stream->width;
+       if (dimensions & HEIGHT)
+               n /= stream->height;
+
+       if (stream->frames > n)
+               enprintf(status, "%s: %s%svideo is too large\n",
+                        stream->file, prefix ? prefix : "",
+                        (prefix && *prefix) ? " " : "");
 }
 
 
@@ -220,7 +245,7 @@ get_pixel_format(const char *specified, const char *current)
 
 
 int
-enread_frame(int status, struct stream *stream, void *buf, size_t n)
+enread_segment(int status, struct stream *stream, void *buf, size_t n)
 {
        char *buffer = buf;
        ssize_t r;
@@ -267,13 +292,10 @@ void
 nprocess_each_frame_segmented(int status, struct stream *stream, int 
output_fd, const char* output_fname,
                              void (*process)(struct stream *stream, size_t n, 
size_t frame))
 {
-       size_t frame_size, frame, r, n;
-
-       encheck_frame_size(status, stream->width, stream->height, 
stream->pixel_size, 0, stream->file);
-       frame_size = stream->height * stream->width * stream->pixel_size;
-
+       size_t frame, r, n;
+       encheck_dimensions(status, stream, WIDTH | HEIGHT, NULL);
        for (frame = 0; frame < stream->frames; frame++) {
-               for (n = frame_size; n; n -= r) {
+               for (n = stream->frame_size; n; n -= r) {
                        if (stream->ptr < n && !enread_stream(status, stream, 
SIZE_MAX))
                                enprintf(status, "%s: file is shorter than 
expected\n", stream->file);
                        r = stream->ptr - (stream->ptr % stream->pixel_size);
@@ -386,39 +408,38 @@ nprocess_multiple_streams(int status, struct stream 
*streams, size_t n_streams,
 void
 nprocess_each_frame_two_streams(int status, struct stream *left, struct stream 
*right, int output_fd, const char* output_fname,
                                void (*process)(char *restrict output, char 
*restrict lbuf, char *restrict rbuf,
-                                               struct stream *left, struct 
stream *right, size_t ln, size_t rn))
+                                               struct stream *left, struct 
stream *right))
 {
-       size_t lframe_size, rframe_size;
        char *lbuf, *rbuf, *image;
 
-       encheck_frame_size(status, left->width,  left->height,  
left->pixel_size,  0, left->file);
-       encheck_frame_size(status, right->width, right->height, 
right->pixel_size, 0, right->file);
-       lframe_size = left->height  * left->width  * left->pixel_size;
-       rframe_size = right->height * right->width * right->pixel_size;
+       encheck_dimensions(status, left,  WIDTH | HEIGHT, NULL);
+       encheck_dimensions(status, right, WIDTH | HEIGHT, NULL);
 
-       if (lframe_size > SIZE_MAX - lframe_size || 2 * lframe_size > SIZE_MAX 
- rframe_size)
+       if (left->frame_size > SIZE_MAX - left->frame_size ||
+           2 * left->frame_size > SIZE_MAX - right->frame_size)
                enprintf(status, "video frame is too large\n");
 
-       image = mmap(0, 2 * lframe_size + lframe_size, PROT_READ | PROT_WRITE, 
MAP_ANONYMOUS | MAP_SHARED, -1, 0);
+       image = mmap(0, 2 * left->frame_size + right->frame_size,
+                    PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
        if (image == MAP_FAILED)
                enprintf(status, "mmap:");
-       lbuf = image + 1 * lframe_size;
-       rbuf = image + 2 * lframe_size;
+       lbuf = image + 1 * left->frame_size;
+       rbuf = image + 2 * left->frame_size;
 
        for (;;) {
-               if (!enread_frame(status, left, lbuf, lframe_size)) {
+               if (!enread_frame(status, left, lbuf)) {
                        close(left->fd);
                        left->fd = -1;
                        break;
                }
-               if (!enread_frame(status, right, rbuf, rframe_size)) {
+               if (!enread_frame(status, right, rbuf)) {
                        close(right->fd);
                        right->fd = -1;
                        break;
                }
 
-               process(image, lbuf, rbuf, left, right, lframe_size, 
rframe_size);
-               enwriteall(status, output_fd, image, lframe_size, output_fname);
+               process(image, lbuf, rbuf, left, right);
+               enwriteall(status, output_fd, image, left->frame_size, 
output_fname);
        }
 
        if (right->fd >= 0)
@@ -426,9 +447,9 @@ nprocess_each_frame_two_streams(int status, struct stream 
*left, struct stream *
 
        if (left->fd >= 0) {
                memcpy(image, lbuf, left->ptr);
-               while (enread_frame(status, left, lbuf, lframe_size))
-                       enwriteall(status, output_fd, image, lframe_size, 
output_fname);
+               while (enread_frame(status, left, lbuf))
+                       enwriteall(status, output_fd, image, left->frame_size, 
output_fname);
        }
 
-       munmap(image, 2 * lframe_size + rframe_size);
+       munmap(image, 2 * left->frame_size + right->frame_size);
 }
diff --git a/src/stream.h b/src/stream.h
index 238f026..e419c89 100644
--- a/src/stream.h
+++ b/src/stream.h
@@ -3,7 +3,7 @@
 #include <stddef.h>
 #include <stdio.h>
 
-#define STREAM_HEAD_MAX (3 * 3 * sizeof(size_t) + sizeof(((struct stream 
*)0)->pixfmt) + 10)
+#define STREAM_HEAD_MAX (3 * INTSTRLEN(size_t) + sizeof(((struct stream 
*)0)->pixfmt) + 10)
 
 #define SPRINTF_HEAD_ZN(BUF, FRAMES, WIDTH, HEIGHT, PIXFMT, LENP)\
        sprintf(BUF, "%zu %zu %zu %s\n%cuivf%zn",\
@@ -21,17 +21,17 @@
        fprintf(FP, FFRAMES" "FWIDTH" "FHEIGHT" %s\n%cuivf",\
                FRAMES, WIDTH, HEIGHT, PIXFMT, 0)
 
-#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 eread_stream(...)      enread_stream(1, __VA_ARGS__)
-#define einf_check_fd(...)     eninf_check_fd(1, __VA_ARGS__)
-#define echeck_frame_size(...) encheck_frame_size(1, __VA_ARGS__)
-#define echeck_compat(...)     encheck_compat(1, __VA_ARGS__)
-#define eread_frame(...)       enread_frame(1, __VA_ARGS__)
-
-#define enread_row(...) enread_frame(__VA_ARGS__)
-#define eread_row(...)  eread_frame(__VA_ARGS__)
+#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 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__)
+#define echeck_dimensions_custom(...) encheck_dimensions_custom(1, __VA_ARGS__)
+#define echeck_compat(...)            encheck_compat(1, __VA_ARGS__)
+#define eread_segment(...)            enread_segment(1, __VA_ARGS__)
+#define eread_frame(...)              enread_frame(1, __VA_ARGS__)
+#define eread_row(...)                enread_row(1, __VA_ARGS__)
 
 #define process_stream(...)                 nprocess_stream(1, __VA_ARGS__)
 #define process_each_frame_segmented(...)   nprocess_each_frame_segmented(1, 
__VA_ARGS__)
@@ -39,6 +39,12 @@
 #define process_multiple_streams(...)       nprocess_multiple_streams(1, 
__VA_ARGS__)
 #define process_each_frame_two_streams(...) nprocess_each_frame_two_streams(1, 
__VA_ARGS__)
 
+enum dimension {
+       WIDTH = 1,
+       HEIGHT = 2,
+       LENGTH = 4
+};
+
 struct stream {
        size_t frames;
        size_t width;
@@ -54,6 +60,9 @@ struct stream {
        char buf[BUFSIZ];
        const char *file;
        size_t headlen;
+       size_t row_size;
+       size_t col_size;
+       size_t frame_size;
 };
 
 void eninit_stream(int status, struct stream *stream);
@@ -63,11 +72,10 @@ void enset_pixel_size(int status, struct stream *stream);
 void fprint_stream_head(FILE *fp, struct stream *stream);
 size_t enread_stream(int status, struct stream *stream, size_t n);
 void eninf_check_fd(int status, int fd, const char *file);
-int check_frame_size(size_t width, size_t height, size_t pixel_size);
-void encheck_frame_size(int status, size_t width, size_t height, size_t 
pixel_size, const char *prefix, const char *fname);
+void encheck_dimensions(int status, const struct stream *stream, enum 
dimension dimensions, const char *prefix);
 void encheck_compat(int status, const struct stream *a, const struct stream 
*b);
 const char *get_pixel_format(const char *specified, const char *current);
-int enread_frame(int status, struct stream *stream, void *buf, size_t n);
+int enread_segment(int status, struct stream *stream, void *buf, size_t n);
 
 void nprocess_stream(int status, struct stream *stream, void (*process)(struct 
stream *stream, size_t n));
 
@@ -82,4 +90,33 @@ void nprocess_multiple_streams(int status, struct stream 
*streams, size_t n_stre
 
 void nprocess_each_frame_two_streams(int status, struct stream *left, struct 
stream *right, int output_fd, const char* output_fname,
                                     void (*process)(char *restrict output, 
char *restrict lbuf, char *restrict rbuf,
-                                                    struct stream *left, 
struct stream *right, size_t ln, size_t rn));
+                                                    struct stream *left, 
struct stream *right));
+
+static inline int
+enread_frame(int status, struct stream *stream, void *buf)
+{
+       return enread_segment(status, stream, buf, stream->frame_size);
+}
+
+static inline int
+enread_row(int status, struct stream *stream, void *buf)
+{
+       return enread_segment(status, stream, buf, stream->row_size);
+}
+
+static inline void
+encheck_dimensions_custom(int status, size_t width, size_t height, size_t 
frames,
+                         size_t pixel_size, const char *prefix, const char 
*fname)
+{
+       enum dimension dims = 0;
+       struct stream stream;
+       dims |= width  ? WIDTH  : 0;
+       dims |= height ? HEIGHT : 0;
+       dims |= frames ? LENGTH : 0;
+       stream.width      = width;
+       stream.height     = height;
+       stream.frames     = frames;
+       stream.pixel_size = pixel_size;
+       stream.file       = fname;
+       encheck_dimensions(status, &stream, dims, prefix);
+}
diff --git a/src/util.c b/src/util.c
index 715ce4e..f6150f2 100644
--- a/src/util.c
+++ b/src/util.c
@@ -234,8 +234,8 @@ int
 xenopen(int status, const char *path, int flags, int mode, ...)
 {
        int fd;
-       if (!strncmp(path, "/dev/fd/", sizeof("/dev/fd/") - 1)) {
-               if (!toi(path + sizeof("/dev/fd/") - 1, 0, INT_MAX, &fd))
+       if (!strncmp(path, "/dev/fd/", STRLEN("/dev/fd/"))) {
+               if (!toi(path + STRLEN("/dev/fd/"), 0, INT_MAX, &fd))
                        return fd;
        } else if (!strcmp(path, "/dev/stdin")) {
                return STDIN_FILENO;
diff --git a/src/util.h b/src/util.h
index 42b5df5..ce5f647 100644
--- a/src/util.h
+++ b/src/util.h
@@ -5,6 +5,8 @@
 #define MIN(A, B)         ((A) < (B) ? (A) : (B))
 #define MAX(A, B)         ((A) > (B) ? (A) : (B))
 #define CLIP(A, B, C)     ((B) < (A) ? (A) : (B) > (C) ? (C) : (B))
+#define STRLEN(STR)       (sizeof(STR) - 1)
+#define INTSTRLEN(TYPE)   ((sizeof(TYPE) == 1 ? 3 : (5 * sizeof(TYPE) / 2)) + 
(TYPE)-1 < 0)
 
 #define USAGE(SYNOPSIS)\
        static void usage(void)\

Reply via email to