Add blind-get-colours - blind - suckless command-line video editing utility
 (HTM) git clone git://git.suckless.org/blind
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 975a02fba76fce7526278ea09a27cc0aae608d30
 (DIR) parent 6f4d55793f88540d1b1abd7410e43da83993ad6a
 (HTM) 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:
         M Makefile                            |       1 +
         M README                              |       3 +++
         A man/blind-get-colours.1             |      15 +++++++++++++++
         M man/blind-repeat-tessellation.1     |       3 ++-
         M man/blind.7                         |       3 +++
         A src/blind-get-colours.c             |      88 +++++++++++++++++++++++++++++++
       
       6 files changed, 112 insertions(+), 1 deletion(-)
       ---
 (DIR) 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\
 (DIR) 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
        
 (DIR) 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 >
 (DIR) 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 >
 (DIR) 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
 (DIR) 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;
       +}