blind

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

commit e51098d3bc1ac061d27648ef287f8fa3ced2440d
parent 9fa7221a87817fe41a12a9cbdaa4bac6ee67b07d
Author: Mattias Andrée <maandree@kth.se>
Date:   Sun,  8 Jan 2017 08:52:16 +0100

Rewrite vu-image-to-frame in C for performance and proper error handling

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

Diffstat:
Msrc/util.c | 1-
Asrc/vu-image-to-frame.c | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/vu-image-to-frame.sh | 2--
3 files changed, 116 insertions(+), 3 deletions(-)

diff --git a/src/util.c b/src/util.c @@ -96,7 +96,6 @@ tollu(const char *s, unsigned long long int min, unsigned long long int max, uns int tolli(const char *s, long long int min, long long int max, long long int *out) { - char *end; int sign = 1; unsigned long long int inter; errno = 0; diff --git a/src/vu-image-to-frame.c b/src/vu-image-to-frame.c @@ -0,0 +1,116 @@ +/* See LICENSE file for copyright and license details. */ +#include "arg.h" +#include "util.h" + +#include <sys/wait.h> +#include <string.h> +#include <unistd.h> + +static char * +xmemmem(char *h, const char *n, size_t hn, size_t nn) +{ + char *p, *end; + if (nn > hn) + return NULL; + end = h + (hn - nn + 1); + for (p = h; p != end; p++) { + p = memchr(p, *n, (size_t)(end - p)); + if (!p) + return NULL; + if (!memcmp(p, n, nn)) + return p; + } + return NULL; +} + +static void +usage(void) +{ + eprintf("usage: %s\n", argv0); +} + +int +main(int argc, char *argv[]) +{ + int pipe_rw[2]; + int i, old_fd; + pid_t pid; + int status; + char buf[8096]; + size_t ptr, n; + char *p; + ssize_t r; + + ARGBEGIN { + default: + usage(); + } ARGEND; + if (argc) + usage(); + + if (pipe(pipe_rw)) + eprintf("pipe:"); + + if (pipe_rw[0] == STDIN_FILENO || pipe_rw[1] == STDIN_FILENO) + eprintf("no stdin open\n"); + if (pipe_rw[0] == STDOUT_FILENO || pipe_rw[1] == STDOUT_FILENO) + eprintf("no stdout open\n"); + for (i = 0; i < 2; i++) { + if (pipe_rw[i] == STDERR_FILENO) { + pipe_rw[i] = dup(old_fd = pipe_rw[i]); + if (pipe_rw[i] < 0) + eprintf("dup:"); + close(old_fd); + } + } + + pid = fork(); + if (pid < 0) + eprintf("fork:"); + + if (!pid) { + close(pipe_rw[0]); + if (dup2(pipe_rw[1], STDOUT_FILENO) < 0) + eprintf("dup2:"); + close(pipe_rw[1]); + execlp("convert", "convert", "-", "-depth", "8", "-alpha", "activate", "pam:-", NULL); + eprintf("exec convert:"); + } + + close(pipe_rw[1]); + + for (ptr = 0;;) { + r = read(pipe_rw[0], buf + ptr, sizeof(buf) - ptr); + if (r < 0) + eprintf("read <subprocess>:"); + if (r == 0) + break; + ptr += (size_t)r; + p = xmemmem(buf, "\nENDHDR\n", ptr, sizeof("\nENDHDR\n") - 1); + if (!p) + continue; + p += sizeof("\nENDHDR\n") - 1; + n = (size_t)(p - buf); + memmove(buf, buf + n, ptr - n); + n = ptr - n; + break; + } + + for (;;) { + for (ptr = 0; ptr < n;) { + r = write(STDOUT_FILENO, buf + ptr, n - ptr); + if (r < 0) + eprintf("write <stdout>:"); + ptr += (size_t)r; + } + r = read(pipe_rw[0], buf, sizeof(buf)); + if (r < 0) + eprintf("read <subprocess>:"); + if (r == 0) + break; + n = (size_t)r; + } + + while (waitpid(pid, &status, 0) != pid); + return !!status; +} diff --git a/src/vu-image-to-frame.sh b/src/vu-image-to-frame.sh @@ -1,2 +0,0 @@ -#!/bin/sh -exec convert - -depth 8 -alpha activate pam:- | exec sed '1,/^ENDHDR$/d'