blind-spectrum.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-spectrum.c (4885B)
---
1 /* See LICENSE file for copyright and license details. */
2 #ifndef TYPE
3 #include "common.h"
4
5 USAGE("[-y] [-z depth] spectrum-stream")
6
7 static int luma = 0;
8 static size_t nz = 1;
9
10 #define FILE "blind-spectrum.c"
11 #include "define-functions.h"
12
13 int
14 main(int argc, char *argv[])
15 {
16 struct stream stream, spectrum;
17 void (*process)(struct stream *stream, struct stream *spectrum);
18
19 ARGBEGIN {
20 case 'y':
21 luma = 1;
22 break;
23 case 'z':
24 nz = etozu_flag('z', UARGF(), 1, SIZE_MAX);
25 break;
26 default:
27 usage();
28 } ARGEND;
29
30 if (argc != 1)
31 usage();
32
33 eopen_stream(&stream, NULL);
34 eopen_stream(&spectrum, argv[0]);
35
36 SELECT_PROCESS_FUNCTION(&stream);
37 CHECK_CHANS(&stream, == 3, == (luma ? 1 : stream.luma_chan));
38 CHECK_N_CHAN(&stream, 4, 4);
39
40 if (stream.n_chan != spectrum.n_chan || stream.encoding != spectrum.encoding)
41 eprintf("videos use incompatible pixel formats\n");
42
43 echeck_dimensions(&spectrum, WIDTH | HEIGHT, "spectrum");
44
45 fprint_stream_head(stdout, &stream);
46 efflush(stdout, "<stdout>");
47 process(&stream, &spectrum);
48 return 0;
49 }
50
51 #else
52
53 static void
54 PROCESS(struct stream *stream, struct stream *spectrum)
55 {
56 TYPE *table = emalloc2(nz, spectrum->frame_size);
57 size_t i, n, m = 0;
58 TYPE x, y, z, a, x1, y1, z1, a1, x2, y2, z2, a2, ix, iy, iz, wx, wy, wz;
59 size_t s, t, nx, ny, nxy;
60 nx = spectrum->width;
61 ny = spectrum->height;
62 nxy = nx * ny;
63 if (luma)
64 ny = nxy * nz;
65 do {
66 if (!m) {
67 m = stream->frame_size;
68 for (i = 0; i < nz; i++) {
69 if (!eread_frame(spectrum, ((char *)table) + i * spectrum->frame_size)) {
70 if (!i)
71 goto done;
72 eprintf("%s: incomplete frame set\n", spectrum->file);
73 }
74 }
75 }
76 n = MIN(stream->ptr, m) / stream->pixel_size;
77 for (i = 0; i < n; i++) {
78 if (luma) {
79 iy = ((TYPE *)(stream->buf))[4 * i + 1];
80 iy = MIN(MAX(iy, (TYPE)0), (TYPE)1);
81 iy *= (TYPE)(ny - 1);
82 s = (size_t)iy;
83 t = s + 1;
84 t = t == ny ? ny - 1 : t;
85 wy = mod(iy, (TYPE)1);
86 x = table[4 * s + 0] * (1 - wy) + table[4 * t + 0] * wy;
87 y = table[4 * s + 1] * (1 - wy) + table[4 * t + 1] * wy;
88 z = table[4 * s + 2] * (1 - wy) + table[4 * t + 2] * wy;
89 a = table[4 * s + 3] * (1 - wy) + table[4 * t + 3] * wy;
90 } else {
91 ix = ((TYPE *)(stream->buf))[4 * i + 0];
92 iy = ((TYPE *)(stream->buf))[4 * i + 1];
93 iz = ((TYPE *)(stream->buf))[4 * i + 2];
94 ix = MIN(MAX(ix, (TYPE)0), (TYPE)1);
95 iy = MIN(MAX(iy, (TYPE)0), (TYPE)1);
96 iz = MIN(MAX(iz, (TYPE)0), (TYPE)1);
97 ix *= (TYPE)(nx - 1);
98 iy *= (TYPE)(ny - 1);
99 iz *= (TYPE)(nz - 1);
100 wx = mod(ix, (TYPE)1);
101 wy = mod(iy, (TYPE)1);
102 wz = mod(iz, (TYPE)1);
103 s = (size_t)ix;
104 t = s + 1;
105 t = t == nx ? nx - 1 : t;
106 s += (size_t)iy * nx;
107 t += (size_t)iy * nx;
108 s += (size_t)iz * nxy;
109 t += (size_t)iz * nxy;
110 x = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx;
111 y = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx;
112 z = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx;
113 a = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx;
114 if ((size_t)iy != ny - 1) {
115 s += nx, t += nx;
116 x2 = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx;
117 y2 = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx;
118 z2 = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx;
119 a2 = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx;
120 x = x * (1 - wy) + x2 * wy;
121 y = y * (1 - wy) + y2 * wy;
122 z = z * (1 - wy) + z2 * wy;
123 a = a * (1 - wy) + a2 * wy;
124 s -= nx, t -= nx;
125 }
126 if ((size_t)iz != nz - 1) {
127 s += nxy, t += nxy;
128 x1 = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx;
129 y1 = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx;
130 z1 = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx;
131 a1 = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx;
132 if ((size_t)iy != ny - 1) {
133 s += nx, t += nx;
134 x2 = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx;
135 y2 = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx;
136 z2 = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx;
137 a2 = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx;
138 x1 = x1 * (1 - wy) + x2 * wy;
139 y1 = y1 * (1 - wy) + y2 * wy;
140 z1 = z1 * (1 - wy) + z2 * wy;
141 a1 = a1 * (1 - wy) + a2 * wy;
142 }
143 x = x * (1 - wz) + x1 * wz;
144 y = y * (1 - wz) + y1 * wz;
145 z = z * (1 - wz) + z1 * wz;
146 a = a * (1 - wz) + a1 * wz;
147 }
148 }
149 ((TYPE *)(stream->buf))[4 * i + 0] = x;
150 ((TYPE *)(stream->buf))[4 * i + 1] = y;
151 ((TYPE *)(stream->buf))[4 * i + 2] = z;
152 ((TYPE *)(stream->buf))[4 * i + 3] *= a;
153 }
154 n *= stream->pixel_size;
155 m -= n;
156 ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");
157 memmove(stream->buf, stream->buf + n, stream->ptr -= n);
158 } while (eread_stream(stream, SIZE_MAX));
159 if (stream->ptr)
160 eprintf("%s: incomplete frame\n", stream->file);
161 done:
162 free(table);
163 }
164
165 #endif