commit 34d326d46d31332fa2182793475672617933a939
Author:     Mattias Andrée <[email protected]>
AuthorDate: Wed Jul 5 19:29:13 2017 +0200
Commit:     Mattias Andrée <[email protected]>
CommitDate: Wed Jul 5 19:29:13 2017 +0200

    Add blind-dual-key
    
    Signed-off-by: Mattias Andrée <[email protected]>

diff --git a/Makefile b/Makefile
index a67e3e0..6dc7c25 100644
--- 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\
diff --git a/README b/README
index 261618d..6bdd388 100644
--- 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
 
diff --git a/man/blind-dual-key.1 b/man/blind-dual-key.1
new file mode 100644
index 0000000..6cfe7b8
--- /dev/null
+++ 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 < [email protected] >
diff --git a/man/blind.7 b/man/blind.7
index 79ac8eb..f8295fe 100644
--- 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
diff --git a/src/blind-dual-key.c b/src/blind-dual-key.c
new file mode 100644
index 0000000..8dff71c
--- /dev/null
+++ 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;
+}

Reply via email to