commit 1631fca75013a28db8ee5666fb1f2ad79bfeffe4
parent 7fdc83ab4e18abc18ba8cbb4afd15750fae10b3a
Author: Mattias Andrée <maandree@kth.se>
Date: Sun, 8 Jan 2017 10:32:53 +0100
Add vu-dissolve
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat:
| A | src/vu-dissolve.c | | | 97 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 97 insertions(+), 0 deletions(-)
diff --git a/src/vu-dissolve.c b/src/vu-dissolve.c
@@ -0,0 +1,97 @@
+/* See LICENSE file for copyright and license details. */
+#include "arg.h"
+#include "util.h"
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static unsigned int
+clip(unsigned int value)
+{
+ return value > 255 ? 255 : value;
+}
+
+static void
+usage(void)
+{
+ eprintf("usage: %s [-r] -f frames -w width -h height\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int reverse = 0;
+ size_t frames = 0, width = 0, height = 0;
+ unsigned char buf[8096];
+ size_t frame, h, w, max;
+ size_t ptr = 0, n, i, fm;
+ ssize_t r;
+ double a;
+
+ ARGBEGIN {
+ case 'f':
+ if (tozu(EARGF(usage()), 2, SIZE_MAX, &frames))
+ eprintf("argument of -f must be an integer in [2, %zu]\n", SIZE_MAX);
+ break;
+ case 'w':
+ if (tozu(EARGF(usage()), 1, SIZE_MAX, &width))
+ eprintf("argument of -w must be an integer in [1, %zu]\n", SIZE_MAX);
+ break;
+ case 'h':
+ if (tozu(EARGF(usage()), 1, SIZE_MAX, &height))
+ eprintf("argument of -h must be an integer in [1, %zu]\n", SIZE_MAX);
+ break;
+ case 'r':
+ reverse = 1;
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ if (argc || !frames || !width || !height)
+ usage();
+
+ fm = frames - 1;
+ for (frame = 0; frame < frames; frame++) {
+ for (h = height; h--;) {
+ for (w = width << 2; w; w -= n) {
+ max = sizeof(buf) - ptr < w ? sizeof(buf) - ptr : w;
+ r = read(STDIN_FILENO, buf + ptr, max);
+ if (r < 0)
+ eprintf("read <stdin>:");
+ if (r == 0)
+ eprintf("content is shorter than specified\n");
+ n = ptr += (size_t)r;
+ n -= n & 3;
+ if (reverse) {
+ for (i = 0; i < n; i += 4) {
+ a = buf[i + 3];
+ a = a * (double)frame / fm;
+ a += 0.5;
+ buf[i + 3] = clip((unsigned int)a);
+ }
+ } else {
+ for (i = 0; i < n; i += 4) {
+ a = buf[i + 3];
+ a = a * (double)(fm - frame) / fm;
+ a += 0.5;
+ buf[i + 3] = clip((unsigned int)a);
+ }
+ }
+ for (i = 0; i < n; i += (size_t)r) {
+ r = write(STDOUT_FILENO, buf + i, n - i);
+ if (r < 0)
+ eprintf("write <stdout>:");
+ }
+ memmove(buf, buf + n, ptr -= n);
+ }
+ }
+ }
+
+ return 0;
+}