blind-cone-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-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 pixels\n");
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 - stream->ptr)) {
76 ewriteall(STDOUT_FILENO, buf, ptr * sizeof(*buf), "<stdout>");
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, sizeof(buf), "<stdout>");
119 ptr = 0;
120 }
121 }
122 }
123 }
124 }
125
126 #endif