blind

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

commit d1a5dfdf162d1e1200e7ee1060435d76a028d4c4
parent 34d326d46d31332fa2182793475672617933a939
Author: Mattias Andrée <maandree@kth.se>
Date:   Fri,  7 Jul 2017 20:58:16 +0200

Add blind-chroma-key

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

Diffstat:
Makefile | 1+
README | 3+++
TODO | 4+---
man/blind-chroma-key.1 | 39+++++++++++++++++++++++++++++++++++++++
man/blind-dual-key.1 | 9+++++----
man/blind.7 | 3+++
src/blind-chroma-key.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/blind-sinc-wave.c | 3++-
8 files changed, 146 insertions(+), 8 deletions(-)

diff --git a/Makefile b/Makefile @@ -5,6 +5,7 @@ BIN =\ blind-arithm\ blind-cat-cols\ blind-cat-rows\ + blind-chroma-key\ blind-colour-ciexyz\ blind-colour-srgb\ blind-compress\ diff --git a/README b/README @@ -21,6 +21,9 @@ UTILITIES blind-cat-rows(1) Stack videos vertically + blind-chroma-key(1) + Replace a colour range with transparency + blind-colour-ciexyz(1) Convert CIE XYZ for use with blind-single-colour(1) diff --git a/TODO b/TODO @@ -1,8 +1,6 @@ blind-transform affine transformation by matrix multiplication, -t for tiling, -s for improve quality on downscaling (pixels' neighbours must not change). -blind-chroma-key replace a chroma with transparency or create an mask for the alpha channel. -blind-primary-key replace a primary with transparency or create an mask for the alpha channel, - -g for greyscaled images. +blind-primary-key replace a primary with transparency, -g for greyscaled images. blind-primaries given three selectable primaries split the video into three side-by-side which only one primary active. blind-apply-map remap pixels (distortion) using the X and Y values, -t for tiling, -s for diff --git a/man/blind-chroma-key.1 b/man/blind-chroma-key.1 @@ -0,0 +1,39 @@ +.TH BLIND-CHROMA-KEY 1 blind +.SH NAME +blind-chroma-key - Replace a colour range with transparency +.SH SYNOPSIS +.B blind-chroma-key +.I key-stream +.SH DESCRIPTION +.B blind-chroma-key +reads a video from stdin and colours from +.IR key-stream . +Each frame in +.I key-stream +should contain exactly two pixels. The colour of +the first pixel, and all colours with a distance +from that colour upto the same distance the colour +of the second pixel has to that colour, will be +turned into transparency in the video from stdin, +and the resulting video will be printed to stdout. +.P +If the two colours in a frame from +.I key-stream +have the same alpha value, all matching colours +will be turned into full transparency. Otherwise, +the colours matching the first colour will be +given the transparency specified with the first +colour, all other matching colours will have +a transparency between to two specified alpha +values. However, if alpha value of the second +colour is less than the alpha value of the first +colour, twos alpha values are inverted. +.SH SEE ALSO +.BR blind (7), +.BR blind-from-text (1), +.BR blind-colour-ciexyz (1), +.BR blind-colour-srgb (1), +.BR blind-dual-key (1) +.SH AUTHORS +Mattias Andrée +.RI < maandree@kth.se > diff --git a/man/blind-dual-key.1 b/man/blind-dual-key.1 @@ -9,11 +9,11 @@ blind-dual-key - Apply transparency to a video based on two videos and two key .I dual-X .I dual-Y .I dual-Z -.I dual-video +.I dual-stream .SH DESCRIPTION .B blind-dual-key reads a video from stdin and a video -.IR dual-video . +.IR dual-stream . These two videos should be idential, except with two different background colours. The background colour used in the video from @@ -24,7 +24,7 @@ and .IR Z , using the CIE XYZ colour model. The background colour used in the video from -.I dual-video +.I dual-stream should be specified in the arguments .IR dual-X , .IR dual-Y , @@ -49,7 +49,8 @@ example black and white or green and magenta. .SH SEE ALSO .BR blind (7), .BR blind-colour-ciexyz (1), -.BR blind-colour-srgb (1) +.BR blind-colour-srgb (1), +.BR blind-chroma-key (1) .SH AUTHORS Mattias Andrée .RI < maandree@kth.se > diff --git a/man/blind.7 b/man/blind.7 @@ -28,6 +28,9 @@ Place videos side by side .BR blind-cat-rows (1) Stack videos vertically .TP +.BR blind-chroma-key(1) +Replace a colour range with transparency +.TP .BR blind-colour-ciexyz (1) Convert CIE XYZ for use with .BR blind-single-colour (1) diff --git a/src/blind-chroma-key.c b/src/blind-chroma-key.c @@ -0,0 +1,92 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("key-stream") + + +#define PROCESS(TYPE, SUFFIX)\ + static void\ + process_##SUFFIX(struct stream *stream, struct stream *key)\ + {\ + size_t i, n, m = 0;\ + TYPE x1, y1, z1, a1, a2, variance2, *keyxyza;\ + TYPE x, y, z, d;\ + do {\ + if (!m) {\ + m = stream->frame_size;\ + while (key->ptr < key->frame_size)\ + if (!eread_stream(key, key->frame_size - key->ptr))\ + return;\ + keyxyza = (TYPE *)(key->buf);\ + x1 = keyxyza[0];\ + y1 = keyxyza[1];\ + z1 = keyxyza[2];\ + a1 = keyxyza[3];\ + x = x1 - keyxyza[4];\ + y = y1 - keyxyza[5];\ + z = z1 - keyxyza[6];\ + a2 = keyxyza[7];\ + variance2 = x * x + y * y + z * z;\ + if (a2 > a1) {\ + a1 = 1 - a1;\ + a2 = 1 - a2;\ + }\ + memmove(key->buf, key->buf + key->frame_size,\ + key->ptr -= key->frame_size);\ + }\ + n = MIN(stream->ptr, m) / stream->pixel_size;\ + for (i = 0; i < n; i++) {\ + x = ((TYPE *)(stream->buf))[4 * i + 0] - x1;\ + y = ((TYPE *)(stream->buf))[4 * i + 1] - y1;\ + z = ((TYPE *)(stream->buf))[4 * i + 2] - z1;\ + d = x * x + y * y + z * z;\ + if (d <= variance2) {\ + if (a1 == a2)\ + d = 0;\ + else\ + d = sqrt(d / variance2) * (a1 - a2) + a2;\ + ((TYPE *)(stream->buf))[4 * i + 3] *= d;\ + }\ + }\ + n *= stream->pixel_size;\ + m -= n;\ + ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");\ + memmove(stream->buf, stream->buf + n, stream->ptr -= n);\ + } while (eread_stream(stream, SIZE_MAX));\ + if (stream->ptr)\ + eprintf("%s: incomplete frame\n", stream->file);\ + } + +PROCESS(double, lf) +PROCESS(float, f) + + +int +main(int argc, char *argv[]) +{ + struct stream stream, key; + void (*process)(struct stream *stream, struct stream *key); + + UNOFLAGS(argc != 1); + + eopen_stream(&stream, NULL); + eopen_stream(&key, argv[0]); + + if (!strcmp(stream.pixfmt, "xyza")) + process = process_lf; + else if (!strcmp(stream.pixfmt, "xyza f")) + process = process_f; + else + eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt); + + if (strcmp(stream.pixfmt, key.pixfmt)) + eprintf("videos use incompatible pixel formats\n"); + + if (key.width > 2 || key.height > 2 || key.width * key.height != 2) + eprintf("%s: each frame must contain exactly 2 pixels\n", key.file); + + fprint_stream_head(stdout, &stream); + efflush(stdout, "<stdout>"); + process(&stream, &key); + return 0; +} diff --git a/src/blind-sinc-wave.c b/src/blind-sinc-wave.c @@ -16,7 +16,6 @@ static int equal = 0; TYPE y, theta0y = 0;\ TYPE z, theta0z = 0;\ TYPE a, theta0a = 0;\ - echeck_dimensions(grad, WIDTH | HEIGHT, NULL);\ do {\ if (!m) {\ m = grad->frame_size;\ @@ -107,6 +106,8 @@ main(int argc, char *argv[]) if (have_theta0 && strcmp(stream.pixfmt, theta0.pixfmt)) eprintf("videos use incompatible pixel formats\n"); + echeck_dimensions(&stream, WIDTH | HEIGHT, NULL); + fprint_stream_head(stdout, &stream); efflush(stdout, "<stdout>"); process(&stream, have_theta0 ? &theta0 : NULL);