blind

suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log | Files | Refs | README | 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 }