Add blind-chroma-key - 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 <[email protected]> | |
Date: Fri, 7 Jul 2017 20:58:16 +0200 | |
Add blind-chroma-key | |
Signed-off-by: Mattias Andrée <[email protected]> | |
Diffstat: | |
M Makefile | 1 + | |
M README | 3 +++ | |
M TODO | 4 +--- | |
A man/blind-chroma-key.1 | 39 +++++++++++++++++++++++++++++… | |
M man/blind-dual-key.1 | 9 +++++---- | |
M man/blind.7 | 3 +++ | |
A src/blind-chroma-key.c | 92 +++++++++++++++++++++++++++++… | |
M 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,… | |
improve quality on downscaling (pixels' neighb… | |
-blind-chroma-key replace a chroma with transparency or create an mask f… | |
-blind-primary-key replace a primary with transparency or create an mask… | |
- -g for greyscaled images. | |
+blind-primary-key replace a primary with transparency, -g for greyscale… | |
blind-primaries given three selectable primaries split the vide… | |
only one primary active. | |
blind-apply-map remap pixels (distortion) using the X and Y val… | |
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 < [email protected] > | |
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 v… | |
.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 < [email protected] > | |
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… | |
+ 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 … | |
+ ((TYPE *)(stream->buf))[4 * i + 3] *= … | |
+ }\ | |
+ }\ | |
+ 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… | |
+ | |
+ 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.… | |
+ | |
+ 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); |