blind

suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log | Files | Refs | README | LICENSE

commit 6b998b5ed066aeece1146fe245b35965319b3cbd
parent 3ad57ea82389e52c72c310268bde8b8540fa408e
Author: Mattias Andrée <maandree@kth.se>
Date:   Wed, 10 May 2017 16:59:26 +0200

Cleaner code

Signed-off-by: Mattias Andrée <maandree@kth.se>

Diffstat:
Msrc/blind-arithm.c | 3---
Msrc/blind-compress.c | 16++++++----------
Msrc/blind-concat.c | 11+++--------
Msrc/blind-crop.c | 15++++++---------
Msrc/blind-cut.c | 14++++----------
Msrc/blind-decompress.c | 16+++++++---------
Msrc/blind-dissolve.c | 1-
Msrc/blind-extend.c | 14+++++---------
Msrc/blind-flip.c | 18+++++++-----------
Msrc/blind-flop.c | 45++++++++++++++++++++-------------------------
Msrc/blind-from-image.c | 8+++-----
Msrc/blind-from-text.c | 3---
Msrc/blind-from-video.c | 5+----
Msrc/blind-gauss-blur.c | 45++++++++++++++++++++-------------------------
Msrc/blind-invert-luma.c | 3---
Msrc/blind-next-frame.c | 2--
Msrc/blind-read-head.c | 3+--
Msrc/blind-repeat.c | 3---
Msrc/blind-reverse.c | 44+++++++++++++++++++-------------------------
Msrc/blind-rewrite-head.c | 15+++++----------
Msrc/blind-set-alpha.c | 3---
Msrc/blind-set-luma.c | 3---
Msrc/blind-set-saturation.c | 3---
Msrc/blind-single-colour.c | 2--
Msrc/blind-skip-pattern.c | 13+++++--------
Msrc/blind-split.c | 15++++-----------
Msrc/blind-stack.c | 3---
Msrc/blind-time-blur.c | 12+++++-------
Msrc/blind-to-image.c | 4----
Msrc/blind-to-text.c | 2--
Msrc/blind-to-video.c | 2+-
Msrc/blind-translate.c | 46++++++++++++++++++++--------------------------
Msrc/blind-transpose.c | 32+++++++++++---------------------
Msrc/stream.c | 107+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/stream.h | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Msrc/util.c | 4++--
Msrc/util.h | 2++
37 files changed, 274 insertions(+), 332 deletions(-)

diff --git 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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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)\