blind

suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log | Files | Refs | README | LICENSE

blind-temporal-arithm.c (2413B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include "common.h"
      3 
      4 USAGE("operation")
      5 
      6 /* Because the syntax for a function returning a function pointer is disgusting. */
      7 typedef void (*process_func)(struct stream *stream, void *image);
      8 
      9 #define LIST_OPERATORS(PIXFMT, TYPE)\
     10 	X(add, *img + *buf,     PIXFMT, TYPE)\
     11 	X(mul, *img * *buf,     PIXFMT, TYPE)\
     12 	X(min, MIN(*img, *buf), PIXFMT, TYPE)\
     13 	X(max, MAX(*img, *buf), PIXFMT, TYPE)
     14 
     15 #define X(NAME, ALGO, PIXFMT, TYPE)\
     16 	static void\
     17 	process_##PIXFMT##_##NAME(struct stream *stream, void *image)\
     18 	{\
     19 		TYPE *buf, *img = image;\
     20 		size_t i, n, j = 0, m = stream->frame_size / sizeof(TYPE);\
     21 		do {\
     22 			n = stream->ptr / sizeof(TYPE);\
     23 			buf = (TYPE *)(stream->buf);\
     24 			for (i = 0; i < n; i++, buf++) {\
     25 				*img = ALGO;\
     26 				if (++j == m) {\
     27 					j = 0;\
     28 					img = image;\
     29 				} else {\
     30 					img++;\
     31 				}\
     32 			}\
     33 			n *= sizeof(TYPE);\
     34 			memmove(stream->buf, stream->buf + n, stream->ptr -= n);\
     35 		} while (eread_stream(stream, SIZE_MAX));\
     36 	}
     37 LIST_OPERATORS(lf, double)
     38 LIST_OPERATORS(f, float)
     39 #undef X
     40 
     41 static process_func
     42 get_process_lf(const char *operation)
     43 {
     44 #define X(NAME, _ALGO, PIXFMT, TYPE)\
     45 	if (!strcmp(operation, #NAME)) return process_##PIXFMT##_##NAME;
     46 	LIST_OPERATORS(lf, double)
     47 #undef X
     48 	eprintf("algorithm not recognised: %s\n", operation);
     49 	return NULL;
     50 }
     51 
     52 static process_func
     53 get_process_f(const char *operation)
     54 {
     55 #define X(NAME, _ALGO, PIXFMT, TYPE)\
     56 	if (!strcmp(operation, #NAME)) return process_##PIXFMT##_##NAME;
     57 	LIST_OPERATORS(f, float)
     58 #undef X
     59 	eprintf("algorithm not recognised: %s\n", operation);
     60 	return NULL;
     61 }
     62 
     63 int
     64 main(int argc, char *argv[])
     65 {
     66 	struct stream stream;
     67 	process_func process;
     68 	char *img;
     69 
     70 	UNOFLAGS(argc != 1);
     71 
     72 	eopen_stream(&stream, NULL);
     73 
     74 	if (stream.encoding == DOUBLE)
     75 		process = get_process_lf(argv[0]);
     76 	else if (stream.encoding == FLOAT)
     77 		process = get_process_f(argv[0]);
     78 	else
     79 		eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
     80 
     81 	echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
     82 	img = emalloc(stream.frame_size);
     83 	if (!eread_frame(&stream, img))
     84 		eprintf("video has no frames\n");
     85 
     86 	process(&stream, img);
     87 	if (stream.ptr)
     88 		eprintf("%s: incomplete frame\n", stream.file);
     89 
     90 	stream.frames = 1;
     91 	fprint_stream_head(stdout, &stream);
     92 	efflush(stdout, "<stdout>");
     93 	ewriteall(STDOUT_FILENO, img, stream.frame_size, "<stdout>");
     94 	free(img);
     95 	return 0;
     96 }