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