blind

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

commit 70b03ed486e3fddcc9416a4a3e38576455ebfe98
parent 4cbb81879e31d532b1ef96c4ac7114670303f556
Author: Mattias Andrée <maandree@kth.se>
Date:   Sun,  8 Jan 2017 04:40:23 +0100

Add vu-set-alpha

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

Diffstat:
Asrc/vu-set-alpha.c | 138+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 138 insertions(+), 0 deletions(-)

diff --git a/src/vu-set-alpha.c b/src/vu-set-alpha.c @@ -0,0 +1,138 @@ +/* See LICENSE file for copyright and license details. */ +#include "arg.h" +#include "util.h" + +#include <inttypes.h> +#include <fcntl.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static void +usage(void) +{ + eprintf("usage: %s [-i] colour-stream alpha-stream\n", argv0); +} + +int +main(int argc, char *argv[]) +{ + int invert = 0; + int fd_colour = -1; + int fd_alpha = -1; + unsigned char buf_colour[1024]; + unsigned char buf_alpha[1024]; + size_t ptr_colour = 0; + size_t ptr_alpha = 0; + ssize_t r; + size_t i, n; + unsigned long int re, gr, bl, a1, a2; + + ARGBEGIN { + case 'i': + invert = 1; + break; + default: + usage(); + } ARGEND; + + if (argc != 2) + usage(); + + fd_colour = open(argv[0], O_RDONLY); + if (fd_colour < 0) + eprintf("open %s:", argv[0]); + + fd_alpha = open(argv[1], O_RDONLY); + if (fd_alpha < 0) + eprintf("open %s:", argv[1]); + + for (;;) { + r = read(fd_colour, buf_colour + ptr_colour, sizeof(buf_colour) - ptr_colour); + if (r < 0) { + eprintf("read %s:", argv[0]); + } else if (r == 0) { + close(fd_colour); + fd_colour = -1; + break; + } else { + ptr_colour += (size_t)r; + } + + r = read(fd_alpha, buf_alpha + ptr_alpha, sizeof(buf_alpha) - ptr_alpha); + if (r < 0) { + eprintf("read %s:", argv[0]); + } else if (r == 0) { + close(fd_alpha); + fd_alpha = -1; + break; + } else { + ptr_alpha += (size_t)r; + } + + n = ptr_colour < ptr_alpha ? ptr_colour : ptr_alpha; + n -= n & 3; + ptr_colour -= n; + ptr_alpha -= n; + + for (i = 0; i < n; i += 4) { + re = buf_alpha[i + 0]; + gr = buf_alpha[i + 1]; + bl = buf_alpha[i + 2]; + a1 = buf_alpha[i + 3]; + a2 = buf_colour[i + 3]; + re += gr + bl; + if (invert) + re = 765 - re; + a1 *= a2 * re; + a1 = (a1 * 2 + 3 * 255 * 255) / (3 * 255 * 255 * 2); + buf_colour[i + 3] = a1; + } + + for (i = 0; i < n; i++) { + r = write(STDOUT_FILENO, buf_colour + i, n - i); + if (r < 0) + eprintf("write <stdout>:"); + i += (size_t)r; + } + + if ((n & 3) || ptr_colour != ptr_alpha) { + memmove(buf_colour, buf_colour + n, ptr_colour); + memmove(buf_alpha, buf_alpha + n, ptr_alpha); + } + } + + if (fd_alpha >= 0) + close(fd_alpha); + + while (ptr_colour) { + r = write(STDOUT_FILENO, buf_colour, ptr_colour); + if (r < 0) + eprintf("write <stdout>:"); + ptr_colour -= (size_t)r; + } + + if (fd_colour >= 0) { + for (;;) { + r = read(fd_colour, buf_colour, sizeof(buf_colour)); + if (r < 0) { + eprintf("read %s:", argv[0]); + } else if (r == 0) { + close(fd_colour); + fd_colour = -1; + break; + } else { + n = (size_t)r; + } + + r = write(STDOUT_FILENO, buf_colour, n); + if (r < 0) + eprintf("write <stdout>:"); + n -= (size_t)r; + } + } + + return 0; +}