commit 975a02fba76fce7526278ea09a27cc0aae608d30
parent 6f4d55793f88540d1b1abd7410e43da83993ad6a
Author: Mattias Andrée <maandree@kth.se>
Date: Wed, 12 Jul 2017 02:09:03 +0200
Add blind-get-colours
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat:
6 files changed, 112 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
@@ -33,6 +33,7 @@ BIN =\
blind-from-text\
blind-from-video\
blind-gauss-blur\
+ blind-get-colours\
blind-interleave\
blind-invert-luma\
blind-linear-gradient\
diff --git a/README b/README
@@ -99,6 +99,9 @@ UTILITIES
blind-gauss-blur(1)
Apply Gaussian blur to a video
+ blind-get-colours(1)
+ Get a frame with all colours from a video
+
blind-interleave(1)
Framewise interleave videos
diff --git a/man/blind-get-colours.1 b/man/blind-get-colours.1
@@ -0,0 +1,15 @@
+.TH BLIND-GET-COLOURS 1 blind
+.SH NAME
+blind-get-colours - Get a frame with all colours from a video
+.SH SYNOPSIS
+.B blind-get-colours
+.SH DESCRIPTION
+.B blind-get-colours
+reads a video from stdin and prints a single-frame
+video to stdout contain all colours from the video.
+.SH SEE ALSO
+.BR blind (7),
+.BR blind-repeat-tessellation (1)
+.SH AUTHORS
+Mattias Andrée
+.RI < maandree@kth.se >
diff --git a/man/blind-repeat-tessellation.1 b/man/blind-repeat-tessellation.1
@@ -28,7 +28,8 @@ requires enough free memory to load one full frame of
the video from stdin into memory. A frame requires 32
bytes per pixel it contains.
.SH SEE ALSO
-.BR blind (7)
+.BR blind (7),
+.BR blind-get-colours (1)
.SH AUTHORS
Mattias Andrée
.RI < maandree@kth.se >
diff --git a/man/blind.7 b/man/blind.7
@@ -115,6 +115,9 @@ Converts a regular, cooked video to a blind video
.BR blind-gauss-blur (1)
Apply Gaussian blur to a video
.TP
+.BR blind-get-colours (1)
+Get a frame with all colours from a video
+.TP
.BR blind-interleave (1)
Framewise interleave videos
.TP
diff --git a/src/blind-get-colours.c b/src/blind-get-colours.c
@@ -0,0 +1,88 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+USAGE("")
+
+
+static size_t width;
+
+
+static int
+pixcmp(const void *a, const void *b)
+{
+ return memcmp(a, b, width);
+}
+
+
+static size_t
+unique(char *base, size_t n)
+{
+ size_t i, r = 1;
+ for (i = 1; i < n; i++)
+ if (pixcmp(base + (r - 1) * width, base + i * width) && r++ != i)
+ memcpy(base + (r - 1) * width, base + i * width, width);
+ return r;
+}
+
+
+static size_t
+merge(char **sink, size_t n, char *new, size_t m, size_t *siz)
+{
+ size_t i, j;
+ int c;
+ for (i = j = 0; i < n && j < m; i++) {
+ c = pixcmp(*sink + i * width, new + j * width);
+ if (c > 0) {
+ if (n == *siz) {
+ *siz = n ? n * 2 : 8;
+ *sink = erealloc2(*sink, *siz, width);
+ }
+ n += 1;
+ memmove(*sink + (i + 1) * width, *sink + i * width, (n - i - 1) * width);
+ memcpy(*sink + i * width, new + j * width, width);
+ }
+ j += c >= 0;
+ }
+ m -= j;
+ if (n + m > *siz) {
+ *siz = n + m;
+ *sink = erealloc2(*sink, *siz, width);
+ }
+ memcpy(*sink + n * width, new + j * width, m * width);
+ return n + m;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ struct stream stream;
+ char *colours = NULL;
+ size_t ptr = 0, siz = 0;
+ size_t n, m;
+
+ UNOFLAGS(argc);
+
+ eopen_stream(&stream, NULL);
+ width = stream.pixel_size;
+
+ do {
+ n = stream.ptr / width;
+
+ qsort(stream.buf, n, width, pixcmp);
+ m = unique(stream.buf, n);
+ ptr = merge(&colours, ptr, stream.buf, m, &siz);
+
+ n *= width;
+ memmove(stream.buf, stream.buf + n, stream.ptr -= n);
+ } while (eread_stream(&stream, SIZE_MAX));
+
+ stream.frames = 1;
+ stream.width = ptr;
+ stream.height = 1;
+ fprint_stream_head(stdout, &stream);
+ efflush(stdout, "<stdout>");
+ ewriteall(STDOUT_FILENO, colours, ptr * width, "<stdout>");
+
+ return 0;
+}