blind-stack.c - blind - suckless command-line video editing utility | |
git clone git://git.suckless.org/blind | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
blind-stack.c (2685B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include "common.h" | |
3 | |
4 USAGE("[-bs] bottom-stream ... top-stream") | |
5 | |
6 #define PROCESS(TYPE, BLEND)\ | |
7 do {\ | |
8 TYPE x1, y1, z1, a1;\ | |
9 TYPE x2, y2, z2, a2;\ | |
10 size_t i, j;\ | |
11 for (i = 0; i < n; i += streams->pixel_size) {\ | |
12 x1 = ((TYPE *)(streams[0].buf + i))[0];\ | |
13 y1 = ((TYPE *)(streams[0].buf + i))[1];\ | |
14 z1 = ((TYPE *)(streams[0].buf + i))[2];\ | |
15 a1 = ((TYPE *)(streams[0].buf + i))[3];\ | |
16 for (j = 1; j < n_streams; j++) {\ | |
17 x2 = ((TYPE *)(streams[j].buf + i))[0];\ | |
18 y2 = ((TYPE *)(streams[j].buf + i))[1];\ | |
19 z2 = ((TYPE *)(streams[j].buf + i))[2];\ | |
20 a2 = ((TYPE *)(streams[j].buf + i))[3];\ | |
21 if (BLEND)\ | |
22 a2 /= (TYPE)(j + 1);\ | |
23 a1 *= 1 - a2;\ | |
24 x1 = x1 * a1 + x2 * a2;\ | |
25 y1 = y1 * a1 + y2 * a2;\ | |
26 z1 = z1 * a1 + z2 * a2;\ | |
27 a1 += a2;\ | |
28 }\ | |
29 ((TYPE *)(streams[0].buf + i))[0] = x1;\ | |
30 ((TYPE *)(streams[0].buf + i))[1] = y1;\ | |
31 ((TYPE *)(streams[0].buf + i))[2] = z1;\ | |
32 ((TYPE *)(streams[0].buf + i))[3] = a1;\ | |
33 }\ | |
34 } while (0) | |
35 | |
36 static void process_lf (struct stream *streams, size_t n_streams, size_… | |
37 static void process_lf_b(struct stream *streams, size_t n_streams, size_… | |
38 static void process_f (struct stream *streams, size_t n_streams, size_… | |
39 static void process_f_b (struct stream *streams, size_t n_streams, size_… | |
40 | |
41 int | |
42 main(int argc, char *argv[]) | |
43 { | |
44 struct stream *streams; | |
45 size_t n_streams, i, frames = 0, tmp; | |
46 int blend = 0, shortest = 0; | |
47 void (*process)(struct stream *streams, size_t n_streams, size_t… | |
48 | |
49 ARGBEGIN { | |
50 case 'b': | |
51 blend = 1; | |
52 break; | |
53 case 's': | |
54 shortest = 1; | |
55 frames = SIZE_MAX; | |
56 break; | |
57 default: | |
58 usage(); | |
59 } ARGEND; | |
60 | |
61 if (argc < 2) | |
62 usage(); | |
63 | |
64 n_streams = (size_t)argc; | |
65 streams = ecalloc(n_streams, sizeof(*streams)); | |
66 | |
67 for (i = 0; i < n_streams; i++) { | |
68 eopen_stream(streams + i, argv[i]); | |
69 if (shortest ? | |
70 (streams[i].frames && streams[i].frames < frames) : | |
71 (streams[i].frames || streams[i].frames > frames)) | |
72 frames = streams[i].frames; | |
73 } | |
74 | |
75 if (streams->encoding == DOUBLE) | |
76 process = blend ? process_lf_b :process_lf; | |
77 else if (streams->encoding == FLOAT) | |
78 process = blend ? process_f_b : process_f; | |
79 else | |
80 eprintf("pixel format %s is not supported, try xyza\n", … | |
81 CHECK_ALPHA_CHAN(streams); | |
82 CHECK_N_CHAN(streams, 4, 4); | |
83 | |
84 tmp = streams->frames, streams->frames = frames; | |
85 fprint_stream_head(stdout, streams); | |
86 efflush(stdout, "<stdout>"); | |
87 streams->frames = tmp; | |
88 process_multiple_streams(streams, n_streams, STDOUT_FILENO, "<st… | |
89 | |
90 free(streams); | |
91 return 0; | |
92 } |