blind-cone-gradient.c - blind - suckless command-line video editing utility | |
git clone git://git.suckless.org/blind | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
blind-cone-gradient.c (2630B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #ifndef TYPE | |
3 #include "common.h" | |
4 | |
5 USAGE("[-a | -s] -w width -h height") | |
6 | |
7 static int anticlockwise = 0; | |
8 static int symmetric = 0; | |
9 static size_t width = 0; | |
10 static size_t height = 0; | |
11 static int with_multiplier = 0; | |
12 | |
13 #define FILE "blind-cone-gradient.c" | |
14 #include "define-functions.h" | |
15 | |
16 int | |
17 main(int argc, char *argv[]) | |
18 { | |
19 struct stream stream; | |
20 void (*process)(struct stream *stream); | |
21 | |
22 ARGBEGIN { | |
23 case 'a': | |
24 anticlockwise = 1; | |
25 break; | |
26 case 's': | |
27 symmetric = 1; | |
28 break; | |
29 case 'w': | |
30 width = etozu_flag('w', UARGF(), 1, SIZE_MAX); | |
31 break; | |
32 case 'h': | |
33 height = etozu_flag('h', UARGF(), 1, SIZE_MAX); | |
34 break; | |
35 default: | |
36 usage(); | |
37 } ARGEND; | |
38 | |
39 if (!width || !height || (symmetric && anticlockwise) || argc) | |
40 usage(); | |
41 | |
42 eopen_stream(&stream, NULL); | |
43 | |
44 SELECT_PROCESS_FUNCTION(&stream); | |
45 CHECK_N_CHAN(&stream, 4, 4); | |
46 | |
47 if (stream.width > 3 || stream.height > 3 || | |
48 stream.width * stream.height < 2 || | |
49 stream.width * stream.height > 3) | |
50 eprintf("<stdin>: each frame must contain exactly 2 or 3… | |
51 | |
52 with_multiplier = stream.width * stream.height == 3; | |
53 | |
54 stream.width = width; | |
55 stream.height = height; | |
56 fprint_stream_head(stdout, &stream); | |
57 efflush(stdout, "<stdout>"); | |
58 process(&stream); | |
59 return 0; | |
60 } | |
61 | |
62 #else | |
63 | |
64 static void | |
65 PROCESS(struct stream *stream) | |
66 { | |
67 typedef TYPE pixel_t[4]; | |
68 pixel_t buf[BUFSIZ / sizeof(pixel_t)]; | |
69 TYPE *params, x1, y1, x2, y2; | |
70 TYPE x, y, u, v, m = 1; | |
71 size_t i, ix, iy, ptr = 0; | |
72 | |
73 for (;;) { | |
74 while (stream->ptr < stream->frame_size) { | |
75 if (!eread_stream(stream, stream->frame_size - s… | |
76 ewriteall(STDOUT_FILENO, buf, ptr * size… | |
77 return; | |
78 } | |
79 } | |
80 params = (TYPE *)stream->buf; | |
81 x1 = (params)[0]; | |
82 y1 = (params)[1]; | |
83 x2 = (params)[4]; | |
84 y2 = (params)[5]; | |
85 if (with_multiplier) | |
86 m = (params)[9]; | |
87 memmove(stream->buf, stream->buf + stream->frame_size, | |
88 stream->ptr -= stream->frame_size); | |
89 | |
90 x2 -= x1; | |
91 y2 -= y1; | |
92 u = atan2(y2, x2); | |
93 | |
94 for (iy = 0; iy < height; iy++) { | |
95 y = (TYPE)iy - y1; | |
96 for (ix = 0; ix < width; ix++) { | |
97 x = (TYPE)ix - x1; | |
98 if (!x && !y) { | |
99 v = 0.5; | |
100 } else { | |
101 v = atan2(y, x); | |
102 v -= u; | |
103 v += 2 * (TYPE)M_PI; | |
104 v = mod(v, 2 * (TYPE)M_PI); | |
105 v /= 2 * (TYPE)M_PI; | |
106 if (anticlockwise) | |
107 v = 1 - v; | |
108 v *= m; | |
109 if (symmetric) { | |
110 v = mod(2 * v, (TYPE)2); | |
111 if (v > 1) | |
112 v = 2 - v; | |
113 } | |
114 } | |
115 for (i = 0; i < stream->n_chan; i++) | |
116 buf[ptr][i] = v; | |
117 if (++ptr == ELEMENTSOF(buf)) { | |
118 ewriteall(STDOUT_FILENO, buf, si… | |
119 ptr = 0; | |
120 } | |
121 } | |
122 } | |
123 } | |
124 } | |
125 | |
126 #endif |