blind-radial-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-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 pixels\n");
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 = 0.5;
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 - stream->ptr)) {
67 ewriteall(STDOUT_FILENO, buf, ptr * sizeof(*buf), "<stdout>");
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; i++)
97 buf[ptr][i] = x;
98 if (++ptr == ELEMENTSOF(buf)) {
99 ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>");
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; i++)
117 buf[ptr][i] = x;
118 if (++ptr == ELEMENTSOF(buf)) {
119 ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>");
120 ptr = 0;
121 }
122 }
123 }
124 }
125 }
126 }
127
128 #endif