blind-get-colours.c - 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
       ---
       blind-get-colours.c (1721B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include "common.h"
            3 
            4 USAGE("")
            5 
            6 static size_t width;
            7 
            8 static int
            9 pixcmp(const void *a, const void *b)
           10 {
           11         return memcmp(a, b, width);
           12 }
           13 
           14 static size_t
           15 unique(char *base, size_t n)
           16 {
           17         size_t i, r = 1;
           18         for (i = 1; i < n; i++)
           19                 if (pixcmp(base + (r - 1) * width, base + i * width) && r++ != i)
           20                         memcpy(base + (r - 1) * width, base + i * width, width);
           21         return r;
           22 }
           23 
           24 static size_t
           25 merge(char **sink, size_t n, char *new, size_t m, size_t *siz)
           26 {
           27         size_t i, j;
           28         int c;
           29         for (i = j = 0; i < n && j < m; i++) {
           30                 c = pixcmp(*sink + i * width, new + j * width);
           31                 if (c > 0) {
           32                         if (n == *siz) {
           33                                 *siz = n ? n * 2 : 8;
           34                                 *sink = erealloc2(*sink, *siz, width);
           35                         }
           36                         n += 1;
           37                         memmove(*sink + (i + 1) * width, *sink + i * width, (n - i - 1) * width);
           38                         memcpy(*sink + i * width, new + j * width, width);
           39                 }
           40                 j += c >= 0;
           41         }
           42         m -= j;
           43         if (n + m > *siz) {
           44                 *siz = n + m;
           45                 *sink = erealloc2(*sink, *siz, width);
           46         }
           47         memcpy(*sink + n * width, new + j * width, m * width);
           48         return n + m;
           49 }
           50 
           51 int
           52 main(int argc, char *argv[])
           53 {
           54         struct stream stream;
           55         char *colours = NULL;
           56         size_t ptr = 0, siz = 0;
           57         size_t n, m;
           58 
           59         UNOFLAGS(argc);
           60 
           61         eopen_stream(&stream, NULL);
           62         width = stream.pixel_size;
           63 
           64         do {
           65                 n = stream.ptr / width;
           66                 qsort(stream.buf, n, width, pixcmp);
           67                 m = unique(stream.buf, n);
           68                 ptr = merge(&colours, ptr, stream.buf, m, &siz);
           69                 n *= width;
           70                 memmove(stream.buf, stream.buf + n, stream.ptr -= n);
           71         } while (eread_stream(&stream, SIZE_MAX));
           72 
           73         stream.frames = 1;
           74         stream.width = ptr;
           75         stream.height = 1;
           76         fprint_stream_head(stdout, &stream);
           77         efflush(stdout, "<stdout>");
           78         ewriteall(STDOUT_FILENO, colours, ptr * width, "<stdout>");
           79 
           80         return 0;
           81 }