commit 7be1448a633be40aadd41250f99019438af0c688
parent f69ec5134ffc1fc27764ca70d10be92517ec4498
Author: Mattias Andrée <maandree@kth.se>
Date: Sat, 13 May 2017 22:55:41 +0200
Add blind-kernel
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat:
3 files changed, 140 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -21,6 +21,7 @@ BIN =\
blind-from-video\
blind-gauss-blur\
blind-invert-luma\
+ blind-kernel\
blind-make-kernel\
blind-next-frame\
blind-read-head\
diff --git a/TODO b/TODO
@@ -16,6 +16,8 @@ blind-affine-colour apply an affine transformation to the colour of each pixel,
blind-invert-chroma invert the chroma
blind-from-sent convert a sent presentation to a one-frame-per-slide blind video.
+blind-kirsch https://en.wikipedia.org/wiki/Kirsch_operator
+
blind-from-video: add options to:
* just run ffmpeg just print the output
* convert output from the option above to blind's format,
diff --git a/src/blind-kernel.c b/src/blind-kernel.c
@@ -0,0 +1,137 @@
+/* See LICENSE file for copyright and license details. */
+#include "stream.h"
+#include "util.h"
+
+#include <string.h>
+
+USAGE("[-xyza] kernel [parameter] ...")
+
+#define SUBUSAGE(FORMAT) "Usage: %s [-xyza] " FORMAT, argv0
+#define MATRIX(...) ((const double[]){__VA_ARGS__});
+#define STREQ3(A, B1, B2, B3) (!strcmp(A, B1) || !strcmp(A, B2) || !strcmp(A, B3))
+
+#define LIST_KERNELS\
+ X(kernel_kirsch, "kirsch")\
+ X(kernel_box_blur, "box blur")\
+ X(kernel_sharpen, "sharpen")
+
+static const double *
+kernel_kirsch(int argc, char *argv[], size_t *rows, size_t *cols, double **free_this)
+{
+ *free_this = NULL;
+ *rows = *cols = 3;
+ if (argc != 1)
+ eprintf(SUBUSAGE("'kirsch' direction"));
+ if (STREQ3(argv[0], "1", "N", "N")) return MATRIX( 5, 5, 5, -3, 0, -3, -3, -3, -3);
+ if (STREQ3(argv[0], "2", "NW", "WN")) return MATRIX( 5, 5, -3, 5, 0, -3, -3, -3, -3);
+ if (STREQ3(argv[0], "3", "W", "W")) return MATRIX( 5, -3, -3, 5, 0, -3, 5, -3, -3);
+ if (STREQ3(argv[0], "4", "SW", "WS")) return MATRIX(-3, -3, -3, 5, 0, -3, 5, 5, -3);
+ if (STREQ3(argv[0], "5", "S", "S")) return MATRIX(-3, -3, -3, -3, 0, -3, 5, 5, 5);
+ if (STREQ3(argv[0], "6", "SE", "ES")) return MATRIX(-3, -3, -3, -3, 0, 5, -3, 5, 5);
+ if (STREQ3(argv[0], "7", "E", "E")) return MATRIX(-3, -3, 5, -3, 0, 5, -3, -3, 5);
+ if (STREQ3(argv[0], "8", "NE", "EN")) return MATRIX(-3, 5, 5, -3, 0, 5, -3, -3, -3);
+ eprintf("Unrecognised direction: %s\n", argv[0]);
+ return NULL;
+}
+
+static const double *
+kernel_box_blur(int argc, char *argv[], size_t *rows, size_t *cols, double **free_this)
+{
+ size_t sx, sy, i, n;
+ double *cells, value;
+ *free_this = NULL;
+ *rows = *cols = 3;
+ if (argc > 3)
+ eprintf(SUBUSAGE("'box blur' [spread | x-spread y-spread]"));
+ if (!argc)
+ return MATRIX(1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0,
+ 1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0,
+ 1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0);
+ if (argc == 1) {
+ sx = sy = etozu_arg("spread", argv[0], 0, SIZE_MAX / 2);
+ } else {
+ sx = etozu_arg("x-spread", argv[0], 0, SIZE_MAX / 2);
+ sy = etozu_arg("y-spread", argv[1], 0, SIZE_MAX / 2);
+ }
+ *rows = 2 * sy + 1;
+ *cols = 2 * sx + 1;
+ *free_this = cells = emalloc2(*rows, *cols);
+ n = (2 * sy + 1) * (2 * sx + 1);
+ value = 1 / (double)n;
+ for (i = 0; i < n; i++)
+ cells[i] = value;
+ return cells;
+}
+
+static const double *
+kernel_sharpen(int argc, char *argv[], size_t *rows, size_t *cols, double **free_this)
+{
+ *free_this = NULL;
+ *rows = *cols = 3;
+ if (argc)
+ eprintf(SUBUSAGE("'sharpen'"));
+ return MATRIX(0, -1, 0, -1, 5, -1, 0, -1, -0);
+ (void) argv;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int null_x = 1, null_y = 1, null_z = 1, null_a = 1;
+ size_t rows, cols, y, x, n;
+ const double *kernel, *kern;
+ double *buffer, *buf, *free_this;
+
+ ARGBEGIN {
+ case 'x':
+ null_x = 0;
+ break;
+ case 'y':
+ null_y = 0;
+ break;
+ case 'z':
+ null_z = 0;
+ break;
+ case 'a':
+ null_a = 0;
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ if (null_x && null_y && null_z && null_a)
+ null_x = null_y = null_z = null_a = 0;
+
+ if (0);
+#define X(FUNC, NAME)\
+ else if (!strcmp(argv[0], NAME))\
+ kernel = FUNC(argc, argv + 1, &rows, &cols, &free_this);
+ LIST_KERNELS
+#undef X
+ else
+ eprintf("unrecognised kernel: %s\n", argv[0]);
+
+ FPRINTF_HEAD(stdout, (size_t)1, cols, rows, "xyza");
+ efflush(stdout, "<stdout>");
+
+ buffer = emalloc2(cols, 4 * sizeof(double));
+ n = cols * 4 * sizeof(double);
+
+ kern = kernel;
+ for (y = 0; y < rows; y++) {
+ buf = buffer;
+ for (x = 0; x < cols; x++) {
+ buf[0] = null_x ? 0.0 : *kern;
+ buf[1] = null_y ? 0.0 : *kern;
+ buf[2] = null_z ? 0.0 : *kern;
+ buf[3] = null_a ? 0.0 : *kern;
+ buf += 4;
+ kern++;
+ }
+ ewriteall(STDOUT_FILENO, buffer, n, "<stdout>");
+ }
+
+ free(buffer);
+ free(free_this);
+ return 0;
+}