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 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