blind-spiral-gradient.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-spiral-gradient.c (3993B)
---
1 /* See LICENSE file for copyright and license details. */
2 #ifndef TYPE
3 #include "common.h"
4
5 USAGE("[-s spirals | t] [-al] -w width -h height")
6
7 static int anticlockwise = 0;
8 static int logarithmic = 0;
9 static int angle = 0;
10 static double spirals = 1;
11 static size_t width = 0;
12 static size_t height = 0;
13 static int with_params;
14 static int with_vector;
15
16 #define FILE "blind-spiral-gradient.c"
17 #include "define-functions.h"
18
19 int
20 main(int argc, char *argv[])
21 {
22 struct stream stream;
23 void (*process)(struct stream *stream);
24
25 ARGBEGIN {
26 case 'a':
27 anticlockwise = 1;
28 break;
29 case 'l':
30 logarithmic = 1;
31 break;
32 case 's':
33 spirals = etolf_flag('s', UARGF());
34 if (!spirals)
35 eprintf("the value of -s must not be 0");
36 break;
37 case 't':
38 angle = 1;
39 break;
40 case 'w':
41 width = etozu_flag('w', UARGF(), 1, SIZE_MAX);
42 break;
43 case 'h':
44 height = etozu_flag('h', UARGF(), 1, SIZE_MAX);
45 break;
46 default:
47 usage();
48 } ARGEND;
49
50 if (!width || !height || argc || (spirals != 1 && angle))
51 usage();
52
53 eopen_stream(&stream, NULL);
54
55 SELECT_PROCESS_FUNCTION(&stream);
56 CHECK_N_CHAN(&stream, 4, 4);
57
58 if (stream.width > 5 || stream.height > 5 ||
59 stream.width * stream.height < 2 ||
60 stream.width * stream.height > 5)
61 eprintf("<stdin>: each frame must contain exactly 2, 3, 4, or 5 pixels\n");
62
63 with_params = (stream.width * stream.height) & 1;
64 with_vector = stream.width * stream.height > 3;
65
66 stream.width = width;
67 stream.height = height;
68 fprint_stream_head(stdout, &stream);
69 efflush(stdout, "<stdout>");
70 process(&stream);
71 return 0;
72 }
73
74 #else
75
76 static void
77 PROCESS(struct stream *stream)
78 {
79 typedef TYPE pixel_t[4];
80 pixel_t buf[BUFSIZ / sizeof(pixel_t)];
81 TYPE *params, x1, y1, x2, y2, b, r, u, v;
82 TYPE x, y, a = 0, e = 1, p = 1, k = 1, ep = 1;
83 TYPE x3 = 1, y3 = 0, rd = 1, P, R, Rx, Ry, Pe = 2, Re = 2, PRe = 0.5;
84 size_t i, ix, iy, ptr = 0;
85 for (;;) {
86 while (stream->ptr < stream->frame_size) {
87 if (!eread_stream(stream, stream->frame_size - stream->ptr)) {
88 ewriteall(STDOUT_FILENO, buf, ptr * sizeof(*buf), "<stdout>");
89 return;
90 }
91 }
92 params = (TYPE *)stream->buf;
93 x1 = (params)[0];
94 y1 = (params)[1];
95 x2 = (params)[4];
96 y2 = (params)[5];
97 if (with_vector) {
98 x3 = (params)[8];
99 y3 = (params)[9];
100 Pe = (params)[12];
101 Re = (params)[13];
102 rd = (params)[14];
103 PRe = 1 / sqrt(Pe * Re);
104 b = sqrt(x3 * x3 + y3 * y3);
105 x3 /= b;
106 y3 /= b;
107 }
108 if (with_params) {
109 a = (params)[with_vector ? 16 : 8];
110 e = (params)[with_vector ? 17 : 9];
111 p = (params)[with_vector ? 18 : 10];
112 k = (params)[with_vector ? 19 : 11];
113 ep = 1 / (e * p);
114 }
115 memmove(stream->buf, stream->buf + stream->frame_size,
116 stream->ptr -= stream->frame_size);
117
118 x2 -= x1;
119 y2 -= y1;
120 u = atan2(y2, x2);
121 b = sqrt(x2 * x2 + y2 * y2);
122 b *= (TYPE)spirals;
123 if (logarithmic)
124 b = log(b);
125 b /= pow(2 * (TYPE)M_PI, e);
126
127 for (iy = 0; iy < height; iy++) {
128 y = (TYPE)iy - y1;
129 for (ix = 0; ix < width; ix++) {
130 x = (TYPE)ix - x1;
131 if (!x && !y) {
132 v = 0;
133 } else {
134 v = atan2(y, x);
135 if (anticlockwise)
136 v = -v;
137 v -= u;
138 v += 4 * (TYPE)M_PI;
139 v = mod(v, 2 * (TYPE)M_PI);
140 }
141 if (!with_vector) {
142 r = sqrt(x * x + y * y);
143 } else {
144 P = x * x3 + y * y3;
145 Rx = x - P * x3;
146 Ry = y - P * y3;
147 R = sqrt(Rx * Rx + Ry * Ry) / rd;
148 P = pow(abs(P), Pe);
149 R = pow(abs(R), Re);
150 r = pow(P + R, PRe);
151 }
152 r -= a;
153 if (!logarithmic) {
154 r = pow(r / b, ep);
155 r = (r - v) / (2 * (TYPE)M_PI);
156 } else if (r) {
157 r = log(r / k);
158 r = pow(r / b, ep);
159 r = (r - v) / (2 * (TYPE)M_PI);
160 }
161 if (angle)
162 r = (TYPE)(int)(r + 1) + v / (2 * (TYPE)M_PI);
163 else
164 r = mod(r, 1 / (TYPE)spirals) * (TYPE)spirals + r - mod(r, (TYPE)1);
165 for (i = 0; i < stream->n_chan; i++)
166 buf[ptr][i] = r;
167 if (++ptr == ELEMENTSOF(buf)) {
168 ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>");
169 ptr = 0;
170 }
171 }
172 }
173 }
174 }
175
176 #endif