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