| blind-cone-gradient.c - blind - suckless command-line video editing utility | |
| git clone git://git.suckless.org/blind | |
| Log | |
| Files | |
| Refs | |
| README | |
| 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… | |
| 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 - s… | |
| 76 ewriteall(STDOUT_FILENO, buf, ptr * size… | |
| 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, si… | |
| 119 ptr = 0; | |
| 120 } | |
| 121 } | |
| 122 } | |
| 123 } | |
| 124 } | |
| 125 | |
| 126 #endif |