Introduction
Introduction Statistics Contact Development Disclaimer Help
blind-temporal-mean.c - blind - suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log
Files
Refs
README
LICENSE
---
blind-temporal-mean.c (5440B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include "common.h"
3
4 USAGE("[-d | -g | -h | -l power-stream | -p power-stream | -v]")
5 /* TODO add [-w weight-stream] for [-ghlpv] */
6
7 /* Because the syntax for a function returning a function pointer is dis…
8 typedef void (*process_func)(struct stream *stream, void *buffer, void *…
9
10 /*
11 * X-parameter 1: method enum value
12 * X-parameter 2: identifier-friendly name
13 * X-parameter 3: images
14 * X-parameter 4: action for first frame
15 * X-parameter 5: pre-process assignments
16 * X-parameter 6: subcell processing
17 * X-parameter 7: pre-finalise assignments
18 * X-parameter 8: subcell finalisation
19 */
20 #define LIST_MEANS(TYPE)\
21 /* [default] arithmetic mean */\
22 X(ARITHMETIC, arithmetic, 1, COPY_FRAME,, *img += *buf,\
23 a = (TYPE)1 / (TYPE)frame, *img *= a)\
24 /* standard deviation */\
25 X(STANDARD_DEVIATION, sd, 2, ZERO_AND_PROCESS_FRAME,, (*img += *…
26 a = (TYPE)1 / (TYPE)frame, *img = nnpow((*img - *aux * *aux * …
27 /* geometric mean */\
28 X(GEOMETRIC, geometric, 1, COPY_FRAME,, *img *= *buf,\
29 a = (TYPE)1 / (TYPE)frame, *img = nnpow(*img, a))\
30 /* harmonic mean */\
31 X(HARMONIC, harmonic, 1, ZERO_AND_PROCESS_FRAME,, *img += (TYPE)…
32 a = (TYPE)frame, *img = a / *img)\
33 /* Lehmer mean */\
34 X(LEHMER, lehmer, 2, ZERO_AND_PROCESS_FRAME,,\
35 (*img += nnpow(*buf, *pows), *aux += nnpow(*buf, *pows - (TYPE…
36 /* power mean (Hölder mean) (m = 2 for root square mean; m = 3 …
37 X(POWER, power, 1, ZERO_AND_PROCESS_FRAME,, *img += nnpow(*buf, …
38 a = (TYPE)1 / (TYPE)frame, *img = a * nnpow(*img, (TYPE)1 / *p…
39 /* variance */\
40 X(VARIANCE, variance, 2, ZERO_AND_PROCESS_FRAME,, (*img += *buf …
41 a = (TYPE)1 / (TYPE)frame, *img = (*img - *aux * *aux * a) * a)
42
43 enum first_frame_action {
44 COPY_FRAME,
45 PROCESS_FRAME,
46 ZERO_AND_PROCESS_FRAME,
47 };
48
49 #define X(V, ...) V,
50 enum method { LIST_MEANS() };
51 #undef X
52
53 static void *powerbuf = NULL;
54
55 #define MAKE_PROCESS(PIXFMT, TYPE,\
56 _1, NAME, _3, _4, PRE_PROCESS, PROCESS_SUBCELL, PRE…
57 static void\
58 process_##PIXFMT##_##NAME(struct stream *stream, void *buffer, v…
59 {\
60 TYPE *buf = buffer, *img = image, a, *pows = powerbuf;\
61 TYPE *aux = (TYPE *)(((char *)image) + stream->frame_siz…
62 size_t x, y, z;\
63 if (!buf) {\
64 PRE_FINALISE;\
65 for (z = 0; z < stream->n_chan; z++)\
66 for (y = 0; y < stream->height; y++)\
67 for (x = 0; x < stream->width; x…
68 FINALISE_SUBCELL;\
69 } else {\
70 PRE_PROCESS;\
71 for (z = 0; z < stream->n_chan; z++)\
72 for (y = 0; y < stream->height; y++)\
73 for (x = 0; x < stream->width; x…
74 PROCESS_SUBCELL;\
75 }\
76 }\
77 (void) aux, (void) a, (void) pows, (void) frame;\
78 }
79 #define X(...) MAKE_PROCESS(lf, double, __VA_ARGS__)
80 LIST_MEANS(double)
81 #undef X
82 #define X(...) MAKE_PROCESS(f, float, __VA_ARGS__)
83 LIST_MEANS(float)
84 #undef X
85 #undef MAKE_PROCESS
86
87 #define X(ID, NAME, ...) [ID] = process_lf_##NAME,
88 static const process_func process_functions_lf[] = { LIST_MEANS() };
89 #undef X
90
91 #define X(ID, NAME, ...) [ID] = process_f_##NAME,
92 static const process_func process_functions_f[] = { LIST_MEANS() };
93 #undef X
94
95 int
96 main(int argc, char *argv[])
97 {
98 struct stream stream, power;
99 void *buf, *img;
100 process_func process;
101 size_t frames, images;
102 enum method method = ARITHMETIC;
103 enum first_frame_action first_frame_action;
104 const char *power_file = NULL;
105
106 ARGBEGIN {
107 case 'd':
108 method = STANDARD_DEVIATION;
109 break;
110 case 'g':
111 method = GEOMETRIC;
112 break;
113 case 'h':
114 method = HARMONIC;
115 break;
116 case 'l':
117 method = LEHMER;
118 power_file = UARGF();
119 break;
120 case 'p':
121 method = POWER;
122 power_file = UARGF();
123 break;
124 case 'v':
125 method = VARIANCE;
126 break;
127 default:
128 usage();
129 } ARGEND;
130
131 if (argc)
132 usage();
133
134 #define X(ID, _2, IMAGES, FIRST_FRAME_ACTION, ...)\
135 case ID:\
136 images = IMAGES;\
137 first_frame_action = FIRST_FRAME_ACTION;\
138 break;
139 switch (method) {
140 LIST_MEANS()
141 default:
142 abort();
143 }
144 #undef X
145
146 eopen_stream(&stream, NULL);
147 if (power_file != NULL) {
148 eopen_stream(&power, power_file);
149 echeck_compat(&stream, &power);
150 powerbuf = emalloc(power.frame_size);
151 if (!eread_frame(&power, powerbuf))
152 eprintf("%s is no frames\n", power_file);
153 }
154
155 if (stream.encoding == DOUBLE)
156 process = process_functions_lf[method];
157 else if (stream.encoding == FLOAT)
158 process = process_functions_f[method];
159 else
160 eprintf("pixel format %s is not supported, try xyza\n", …
161
162 stream.frames = 1;
163 echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
164 fprint_stream_head(stdout, &stream);
165 efflush(stdout, "<stdout>");
166 buf = emalloc(stream.frame_size);
167 if (first_frame_action == ZERO_AND_PROCESS_FRAME)
168 img = ecalloc(images, stream.frame_size);
169 else
170 img = emalloc2(images, stream.frame_size);
171
172 frames = 0;
173 if (first_frame_action == COPY_FRAME) {
174 if (!eread_frame(&stream, img))
175 eprintf("video is no frames\n");
176 frames++;
177 }
178 for (; eread_frame(&stream, buf); frames++)
179 process(&stream, buf, img, frames);
180 if (!frames)
181 eprintf("video has no frames\n");
182 process(&stream, NULL, img, frames);
183
184 ewriteall(STDOUT_FILENO, img, stream.frame_size, "<stdout>");
185 free(buf);
186 free(img);
187 free(powerbuf);
188 return 0;
189 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.