URI: 
       Add blind-dual-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 34d326d46d31332fa2182793475672617933a939
   DIR parent 88752940275b41cf4b8c978f226ff7d55a5f6575
  HTML Author: Mattias Andrée <maandree@kth.se>
       Date:   Wed,  5 Jul 2017 19:29:13 +0200
       
       Add blind-dual-key
       
       Signed-off-by: Mattias Andrée <maandree@kth.se>
       
       Diffstat:
         M Makefile                            |       1 +
         M README                              |       3 +++
         A man/blind-dual-key.1                |      55 +++++++++++++++++++++++++++++++
         M man/blind.7                         |       3 +++
         A src/blind-dual-key.c                |      81 ++++++++++++++++++++++++++++++
       
       5 files changed, 143 insertions(+), 0 deletions(-)
       ---
   DIR diff --git a/Makefile b/Makefile
       @@ -20,6 +20,7 @@ BIN =\
                blind-dissolve\
                blind-dot-product\
                blind-double-sine-wave\
       +        blind-dual-key\
                blind-extend\
                blind-extract-alpha\
                blind-find-rectangle\
   DIR diff --git a/README b/README
       @@ -60,6 +60,9 @@ UTILITIES
               blind-double-sine-wave(1)
                      Apply double-sine-wave repetition to gradient
        
       +       blind-dual-key(1)
       +              Apply transparency to a video based on two videos and two key
       +
               blind-extend(1)
                      Add margins to a video
        
   DIR diff --git a/man/blind-dual-key.1 b/man/blind-dual-key.1
       @@ -0,0 +1,55 @@
       +.TH BLIND-DUAL-KEY 1 blind
       +.SH NAME
       +blind-dual-key - Apply transparency to a video based on two videos and two key
       +.SH SYNOPSIS
       +.B blind-dual-key
       +.I X
       +.I Y
       +.I Z
       +.I dual-X
       +.I dual-Y
       +.I dual-Z
       +.I dual-video
       +.SH DESCRIPTION
       +.B blind-dual-key
       +reads a video from stdin and a video
       +.IR dual-video .
       +These two videos should be idential, except
       +with two different background colours. The
       +background colour used in the video from
       +stdin should be specified in the arguments
       +.IR X ,
       +.IR Y ,
       +and
       +.IR Z ,
       +using the CIE XYZ colour model. The
       +background colour used in the video from
       +.I dual-video
       +should be specified in the arguments
       +.IR dual-X ,
       +.IR dual-Y ,
       +and
       +.IR dual-Z ,
       +using the CIE XYZ colour model. Using this information,
       +.B blind-dual-key
       +reconstruct the alpha channel of the video
       +and prints the video with its alpha channel to
       +stdout.
       +.SH NOTES
       +.B blind-dual-key
       +may be changed in the future to use some other colour model,
       +therefore, it is recommended to also use
       +.BR blind-colour-ciexyz (1)
       +if you are specifying the colour in CIE XYZ.
       +.P
       +When making a video whose transparancy is recovered with
       +.BR blind-dual-key ,
       +select to opposite background colours, for
       +example black and white or green and magenta.
       +.SH SEE ALSO
       +.BR blind (7),
       +.BR blind-colour-ciexyz (1),
       +.BR blind-colour-srgb (1)
       +.SH AUTHORS
       +Mattias Andrée
       +.RI < maandree@kth.se >
   DIR diff --git a/man/blind.7 b/man/blind.7
       @@ -76,6 +76,9 @@ Calculate the dot product of colours in a video
        .BR blind-double-sine-wave (1)
        Apply double-sine-wave repetition to gradient
        .TP
       +.BR blind-dual-key(1)
       +Apply transparency to a video based on two videos and two key
       +.TP
        .BR blind-extend (1)
        Add margins to a video
        .TP
   DIR diff --git a/src/blind-dual-key.c b/src/blind-dual-key.c
       @@ -0,0 +1,81 @@
       +/* See LICENSE file for copyright and license details. */
       +#include "common.h"
       +
       +USAGE("[-m] X Y Z dual-X dual-Y dual-Z dual-stream")
       +
       +static double X1, Y1, Z1, X2, Y2, Z2;
       +
       +#define PROCESS(TYPE)\
       +        do {\
       +                size_t i;\
       +                TYPE x1k = (TYPE)X1, y1k = (TYPE)Y1, z1k = (TYPE)Z1;\
       +                TYPE x2k = (TYPE)X2, y2k = (TYPE)Y2, z2k = (TYPE)Z2;\
       +                TYPE x1, y1, z1, a1, x2, y2, z2, a2;\
       +                TYPE alpha, xalpha, yalpha, zalpha;\
       +                for (i = 0; i < n; i += stream->pixel_size) {\
       +                        x1 = ((TYPE *)(stream->buf + i))[0];\
       +                        y1 = ((TYPE *)(stream->buf + i))[1];\
       +                        z1 = ((TYPE *)(stream->buf + i))[2];\
       +                        a1 = ((TYPE *)(stream->buf + i))[3];\
       +                        x2 = ((TYPE *)(dual->buf + i))[0];\
       +                        y2 = ((TYPE *)(dual->buf + i))[1];\
       +                        z2 = ((TYPE *)(dual->buf + i))[2];\
       +                        a2 = ((TYPE *)(dual->buf + i))[3];\
       +                        if (x1 == x2 && y1 == y2 && z1 == z2) {\
       +                                if (a1 != a2)\
       +                                        ((TYPE *)(stream->buf + i))[3] = (a1 + a2) / 2;\
       +                                continue;\
       +                        }\
       +                        xalpha = x1 == x2 ? (TYPE)0 : (x2 - x1 + x1k - x2k) / (x1k - x2k);\
       +                        yalpha = y1 == y2 ? (TYPE)0 : (y2 - y1 + y1k - y2k) / (y1k - y2k);\
       +                        zalpha = z1 == z2 ? (TYPE)0 : (z2 - z1 + z1k - z2k) / (z1k - z2k);\
       +                        alpha = xalpha > yalpha ? xalpha : yalpha;\
       +                        alpha = alpha  > zalpha ? alpha  : zalpha;\
       +                        if (!alpha) {\
       +                                ((TYPE *)(stream->buf + i))[0] = (TYPE)0;\
       +                                ((TYPE *)(stream->buf + i))[1] = (TYPE)0;\
       +                                ((TYPE *)(stream->buf + i))[2] = (TYPE)0;\
       +                                ((TYPE *)(stream->buf + i))[3] = (TYPE)0;\
       +                        } else {\
       +                                ((TYPE *)(stream->buf + i))[0] = ((x1 - x1k + x2 - x2k) / alpha + x1k + x2k) / 2;\
       +                                ((TYPE *)(stream->buf + i))[1] = ((y1 - y1k + y2 - y2k) / alpha + y1k + y2k) / 2;\
       +                                ((TYPE *)(stream->buf + i))[2] = ((z1 - z1k + z2 - z2k) / alpha + z1k + z2k) / 2;\
       +                                ((TYPE *)(stream->buf + i))[3] = (a1 + a2) / 2 * alpha;\
       +                        }\
       +                }\
       +        } while (0)
       +
       +static void process_lf(struct stream *stream, struct stream *dual, size_t n) {PROCESS(double);}
       +static void process_f (struct stream *stream, struct stream *dual, size_t n) {PROCESS(float);}
       +
       +int
       +main(int argc, char *argv[])
       +{
       +        struct stream stream, dual;
       +        void (*process)(struct stream *stream, struct stream *dual, size_t n);
       +
       +        UNOFLAGS(argc != 7);
       +
       +        X1 = etolf_arg("the X value", argv[0]);
       +        Y1 = etolf_arg("the Y value", argv[1]);
       +        Z1 = etolf_arg("the Z value", argv[2]);
       +
       +        X2 = etolf_arg("the dual-X value", argv[3]);
       +        Y2 = etolf_arg("the dual-Y value", argv[4]);
       +        Z2 = etolf_arg("the dual-Z value", argv[5]);
       +
       +        eopen_stream(&stream, NULL);
       +        eopen_stream(&dual, argv[6]);
       +
       +        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);
       +
       +        fprint_stream_head(stdout, &stream);
       +        efflush(stdout, "<stdout>");
       +        process_two_streams(&stream, &dual, STDOUT_FILENO, "<stdout>", process);
       +        return 0;
       +}