Introduction
Introduction Statistics Contact Development Disclaimer Help
blind-spatial-mean.c - blind - suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log
Files
Refs
README
LICENSE
---
blind-spatial-mean.c (4867B)
---
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);
9
10 #define C (j & 3)
11 /*
12 * X-parameter 1: method enum value
13 * X-parameter 2: identifier-friendly name
14 * X-parameter 3: initial assignments
15 * X-parameter 4: initial value
16 * X-parameter 5: subcell processing
17 * X-parameter 6: subcell finalisation
18 */
19 #define LIST_MEANS(TYPE)\
20 /* [default] arithmetic mean */\
21 X(ARITHMETIC, arithmetic,, 0, img[C] += *buf, img[C] /= pixels)\
22 /* standard deviation */\
23 X(STANDARD_DEVIATION, sd,, 0, (img[C] += *buf * *buf, aux[C] += …
24 img[C] = nnpow((img[C] - aux[C] * aux[C] / pixels) / pixels, (…
25 /* geometric mean */\
26 X(GEOMETRIC, geometric,, 1, img[C] *= *buf, img[C] = nnpow(img[C…
27 /* harmonic mean */\
28 X(HARMONIC, harmonic,, 0, img[C] += (TYPE)1 / *buf, img[C] = pix…
29 /* Lehmer mean */\
30 X(LEHMER, lehmer, (a[0] = powers[0] - (TYPE)1, a[1] = powers[1] …
31 a[2] = powers[2] - (TYPE)1, a[3] = powers[3] …
32 (img[C] += nnpow(*buf, powers[C]), aux[C] += nnpow(*buf, a[C])…
33 /* power mean (Hölder mean) (m = 2 for root square mean; m = 3 …
34 X(POWER, power,, 0, img[C] += nnpow(*buf, powers[C]),\
35 img[C] = nnpow(img[C], (TYPE)1 / powers[C]) / pixels)\
36 /* variance */\
37 X(VARIANCE, variance,, 0, (img[C] += *buf * *buf, aux[C] += *buf…
38 img[C] = (img[C] - aux[C] * aux[C] / pixels) / pixels)
39
40 #define X(V, ...) V,
41 enum method { LIST_MEANS() };
42 #undef X
43
44 static struct stream power;
45 static const char *power_file = NULL;
46
47 #define MAKE_PROCESS(PIXFMT, TYPE,\
48 _1, NAME, INIT, INITIAL, PROCESS_SUBCELL, FINALISE_…
49 static void\
50 process_##PIXFMT##_##NAME(struct stream *stream)\
51 {\
52 TYPE img[4], aux[4], *buf, a[4], powers[4];\
53 TYPE pixels = (TYPE)(stream->frame_size / sizeof(img));\
54 size_t i, n, j = 0, m = stream->frame_size / sizeof(*img…
55 int first = 1;\
56 do {\
57 n = stream->ptr / stream->pixel_size * stream->n…
58 buf = (TYPE *)(stream->buf);\
59 for (i = 0; i < n; i++, buf++, j++, j %= m) {\
60 if (!j) {\
61 if (!first) {\
62 for (j = 0; j < ELEMENTS…
63 FINALISE_SUBCELL…
64 j = 0;\
65 ewriteall(STDOUT_FILENO,…
66 }\
67 first = 0;\
68 if (power_file && !eread_frame(&…
69 return;\
70 INIT;\
71 img[0] = aux[0] = INITIAL;\
72 img[1] = aux[1] = INITIAL;\
73 img[2] = aux[2] = INITIAL;\
74 img[3] = aux[3] = INITIAL;\
75 }\
76 PROCESS_SUBCELL;\
77 }\
78 n *= sizeof(TYPE);\
79 memmove(stream->buf, stream->buf + n, stream->pt…
80 } while (eread_stream(stream, SIZE_MAX));\
81 if (!first) {\
82 for (j = 0; j < ELEMENTSOF(img); j++)\
83 FINALISE_SUBCELL;\
84 ewriteall(STDOUT_FILENO, img, sizeof(img), "<std…
85 }\
86 (void) aux, (void) a, (void) powers, (void) pixels;\
87 }
88 #define X(...) MAKE_PROCESS(lf, double, __VA_ARGS__)
89 LIST_MEANS(double)
90 #undef X
91 #define X(...) MAKE_PROCESS(f, float, __VA_ARGS__)
92 LIST_MEANS(float)
93 #undef X
94 #undef MAKE_PROCESS
95 #undef C
96
97 #define X(ID, NAME, ...) [ID] = process_lf_##NAME,
98 static const process_func process_functions_lf[] = { LIST_MEANS() };
99 #undef X
100
101 #define X(ID, NAME, ...) [ID] = process_f_##NAME,
102 static const process_func process_functions_f[] = { LIST_MEANS() };
103 #undef X
104
105 int
106 main(int argc, char *argv[])
107 {
108 struct stream stream;
109 process_func process;
110 enum method method = ARITHMETIC;
111
112 ARGBEGIN {
113 case 'd':
114 method = STANDARD_DEVIATION;
115 break;
116 case 'g':
117 method = GEOMETRIC;
118 break;
119 case 'h':
120 method = HARMONIC;
121 break;
122 case 'l':
123 method = LEHMER;
124 power_file = UARGF();
125 break;
126 case 'p':
127 method = POWER;
128 power_file = UARGF();
129 break;
130 case 'v':
131 method = VARIANCE;
132 break;
133 default:
134 usage();
135 } ARGEND;
136
137 if (argc)
138 usage();
139
140 eopen_stream(&stream, NULL);
141 if (power_file != NULL) {
142 eopen_stream(&power, power_file);
143 if (power.width != 1 || power.height != 1)
144 eprintf("%s: videos do not have the 1x1 geometry…
145 if (strcmp(power.pixfmt, stream.pixfmt))
146 eprintf("videos use incompatible pixel formats\n…
147 }
148
149 CHECK_N_CHAN(&stream, 4, 4);
150 if (stream.encoding == DOUBLE)
151 process = process_functions_lf[method];
152 else if (stream.encoding == FLOAT)
153 process = process_functions_f[method];
154 else
155 eprintf("pixel format %s is not supported, try xyza\n", …
156
157 if (DPRINTF_HEAD(STDOUT_FILENO, stream.frames, 1, 1, stream.pixf…
158 eprintf("dprintf:");
159 process(&stream);
160 if (stream.ptr)
161 eprintf("%s: incomplete frame\n", stream.file);
162 return 0;
163 }
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.