aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2017-01-08 08:52:16 +0100
committerMattias Andrée <maandree@kth.se>2017-01-08 08:52:16 +0100
commite51098d3bc1ac061d27648ef287f8fa3ced2440d (patch)
treee59a5dd7fae981c3f35328a934798e0fcbe706dc /src
parentAdd vu-stack (diff)
downloadblind-e51098d3bc1ac061d27648ef287f8fa3ced2440d.tar.gz
blind-e51098d3bc1ac061d27648ef287f8fa3ced2440d.tar.bz2
blind-e51098d3bc1ac061d27648ef287f8fa3ced2440d.tar.xz
Rewrite vu-image-to-frame in C for performance and proper error handling
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'src')
-rw-r--r--src/util.c1
-rw-r--r--src/vu-image-to-frame.c116
-rwxr-xr-xsrc/vu-image-to-frame.sh2
3 files changed, 116 insertions, 3 deletions
diff --git a/src/util.c b/src/util.c
index 2ae3a9f..215a961 100644
--- 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
new file mode 100644
index 0000000..693ddf7
--- /dev/null
+++ 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
deleted file mode 100755
index 42655d5..0000000
--- a/src/vu-image-to-frame.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec convert - -depth 8 -alpha activate pam:- | exec sed '1,/^ENDHDR$/d'