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