URI: 
       Add blind-chroma-key - blind - suckless command-line video editing utility
  HTML git clone git://git.suckless.org/blind
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit d1a5dfdf162d1e1200e7ee1060435d76a028d4c4
   DIR parent 34d326d46d31332fa2182793475672617933a939
  HTML 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:
         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(-)
       ---
   DIR 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\
   DIR 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)
        
   DIR 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
   DIR 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 >
   DIR 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 >
   DIR 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)
   DIR 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;
       +}
   DIR 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);