aboutsummaryrefslogtreecommitdiffstats
path: root/src/blind-get-colours.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2017-07-12 02:09:03 +0200
committerMattias Andrée <maandree@kth.se>2017-07-12 02:09:03 +0200
commit975a02fba76fce7526278ea09a27cc0aae608d30 (patch)
tree6a46f80cfe706c29691982320716f129a5fc8507 /src/blind-get-colours.c
parentAdd blind-repeat-tessellation (diff)
downloadblind-975a02fba76fce7526278ea09a27cc0aae608d30.tar.gz
blind-975a02fba76fce7526278ea09a27cc0aae608d30.tar.bz2
blind-975a02fba76fce7526278ea09a27cc0aae608d30.tar.xz
Add blind-get-colours
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'src/blind-get-colours.c')
-rw-r--r--src/blind-get-colours.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/blind-get-colours.c b/src/blind-get-colours.c
new file mode 100644
index 0000000..87d94b9
--- /dev/null
+++ 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;
+}