blind-multiply-matrices.c - blind - suckless command-line video editing utility | |
git clone git://git.suckless.org/blind | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
blind-multiply-matrices.c (3451B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #ifndef TYPE | |
3 #include "common.h" | |
4 | |
5 USAGE("[-en] leftmost-stream ... rightmost-stream") | |
6 | |
7 static int equal = 0; | |
8 static size_t max_frame_size; | |
9 | |
10 #define FILE "blind-multiply-matrices.c" | |
11 #include "define-functions.h" | |
12 | |
13 int | |
14 main(int argc, char *argv[]) | |
15 { | |
16 struct stream *streams; | |
17 size_t n_streams, i, frames = 0; | |
18 int natural = 0, j; | |
19 char **rev_argv; | |
20 size_t max_width = 0, max_height = 0; | |
21 size_t width = 0, height = 0, w, h; | |
22 void (*process)(struct stream *streams, size_t n_streams); | |
23 | |
24 ARGBEGIN { | |
25 case 'e': | |
26 equal = 1; | |
27 break; | |
28 case 'n': | |
29 natural = 1; | |
30 break; | |
31 default: | |
32 usage(); | |
33 } ARGEND; | |
34 | |
35 if (argc < 2) | |
36 usage(); | |
37 | |
38 if (natural) { | |
39 rev_argv = alloca((size_t)argc * sizeof(*rev_argv)); | |
40 for (j = 0; j < argc; j++) | |
41 rev_argv[j] = argv[argc - 1 - j]; | |
42 argv = rev_argv; | |
43 } | |
44 | |
45 n_streams = (size_t)argc; | |
46 streams = ecalloc(n_streams, sizeof(*streams)); | |
47 | |
48 for (i = 0; i < n_streams; i++) { | |
49 eopen_stream(streams + i, argv[i]); | |
50 if (streams[i].frames && streams[i].frames < frames) | |
51 frames = streams[i].frames; | |
52 if (streams->width > max_width) | |
53 max_width = streams->width; | |
54 if (streams->height > max_height) | |
55 max_height = streams->height; | |
56 } | |
57 for (i = 1; i < n_streams; i++) | |
58 if (strcmp(streams->pixfmt, streams[i].pixfmt)) | |
59 eprintf("videos use incompatible pixel formats\n… | |
60 | |
61 width = streams[n_streams - 1].width; | |
62 height = streams[n_streams - 1].height; | |
63 for (i = n_streams - 1; i--;) { | |
64 if (streams[i].width != height) | |
65 eprintf("videos do not have the compatible geome… | |
66 height = streams[i].height; | |
67 } | |
68 | |
69 SELECT_PROCESS_FUNCTION(streams); | |
70 CHECK_N_CHAN(streams, 1, 4); | |
71 | |
72 w = streams->width, streams->width = max_width; | |
73 h = streams->height, streams->height = max_height; | |
74 echeck_dimensions(streams, WIDTH | HEIGHT, NULL); | |
75 streams->width = width; | |
76 streams->height = height; | |
77 streams->frames = frames; | |
78 fprint_stream_head(stdout, streams); | |
79 streams->width = w; | |
80 streams->height = h; | |
81 efflush(stdout, "<stdout>"); | |
82 max_frame_size = max_width * max_height * streams->pixel_size; | |
83 | |
84 process(streams, n_streams); | |
85 | |
86 free(streams); | |
87 return 0; | |
88 } | |
89 | |
90 #else | |
91 | |
92 static void | |
93 PROCESS(struct stream *streams, size_t n_streams) | |
94 { | |
95 typedef TYPE pixel_t[4]; | |
96 pixel_t *res, *left, *right, *tmp; | |
97 size_t i, j, w, h, h2, x, y, k, r; | |
98 res = emalloc(max_frame_size); | |
99 left = emalloc(max_frame_size); | |
100 right = emalloc(max_frame_size); | |
101 | |
102 while (eread_frame(streams + (n_streams - 1), res)) { | |
103 w = streams[n_streams - 1].width; | |
104 h = streams[n_streams - 1].height; | |
105 for (i = n_streams - 1; i--;) { | |
106 tmp = res, res = right, right = tmp; | |
107 if (!eread_frame(streams + i, left)) | |
108 goto done; | |
109 h2 = streams[i].height; | |
110 memset(res, 0, w * h2 * streams->pixel_size); | |
111 | |
112 /* XXX Is there any significant performance to b… | |
113 if (equal) { | |
114 for (y = r = 0; y < h2; y++) { | |
115 for (x = 0; x < w; x++, r++) { | |
116 for (k = 0; k < h; k++) | |
117 res[r][0] += lef… | |
118 for (j = 1; j < streams-… | |
119 res[r][j] = res[… | |
120 } | |
121 } | |
122 } else { | |
123 for (y = r = 0; y < h2; y++) | |
124 for (x = 0; x < w; x++, r++) | |
125 for (k = 0; k < h; k++) | |
126 for (j = 0; j < … | |
127 res[r][j… | |
128 } | |
129 | |
130 h = h2; | |
131 } | |
132 ewriteall(STDOUT_FILENO, res, streams->frame_size, "<std… | |
133 } | |
134 | |
135 done: | |
136 free(res); | |
137 free(left); | |
138 free(right); | |
139 } | |
140 | |
141 #endif |