blind-linear-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-linear-gradient.c (2091B)
---
1 /* See LICENSE file for copyright and license details. */
2 #ifndef TYPE
3 #include "common.h"
4
5 USAGE("[-b] -w width -h height")
6
7 static int bilinear = 0;
8 static size_t width = 0;
9 static size_t height = 0;
10
11 #define FILE "blind-linear-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 'b':
22 bilinear = 1;
23 break;
24 case 'w':
25 width = etozu_flag('w', UARGF(), 1, SIZE_MAX);
26 break;
27 case 'h':
28 height = etozu_flag('h', UARGF(), 1, SIZE_MAX);
29 break;
30 default:
31 usage();
32 } ARGEND;
33
34 if (!width || !height || argc)
35 usage();
36
37 eopen_stream(&stream, NULL);
38
39 SELECT_PROCESS_FUNCTION(&stream);
40 CHECK_N_CHAN(&stream, 4, 4);
41
42 if (stream.width > 2 || stream.height > 2 || stream.width * stream.height != 2)
43 eprintf("<stdin>: each frame must contain exactly 2 pixels\n");
44
45 stream.width = width;
46 stream.height = height;
47 fprint_stream_head(stdout, &stream);
48 efflush(stdout, "<stdout>");
49 process(&stream);
50 return 0;
51 }
52
53 #else
54
55 static void
56 PROCESS(struct stream *stream)
57 {
58 typedef TYPE pixel_t[4];
59 pixel_t buf[BUFSIZ / sizeof(pixel_t)];
60 TYPE *params, x1, y1, x2, y2, norm2;
61 TYPE x, y;
62 size_t i, ix, iy, ptr = 0;
63
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 memmove(stream->buf, stream->buf + stream->frame_size,
77 stream->ptr -= stream->frame_size);
78
79 x2 -= x1;
80 y2 -= y1;
81 norm2 = x2 * x2 + y2 * y2;
82
83 for (iy = 0; iy < height; iy++) {
84 y = (TYPE)iy - y1;
85 for (ix = 0; ix < width; ix++) {
86 x = (TYPE)ix - x1;
87 x = (x * x2 + y * y2) / norm2;
88 if (bilinear)
89 x = abs(x);
90 for (i = 0; i < stream->n_chan; i++)
91 buf[ptr][i] = x;
92 if (++ptr == ELEMENTSOF(buf)) {
93 ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>");
94 ptr = 0;
95 }
96 }
97 }
98 }
99 }
100
101 #endif