blind

suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log | Files | Refs | README | LICENSE

blind-square-gradient.c (2330B)


      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_multiplier;
     10 
     11 #define FILE "blind-square-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 or 3 pixels\n");
     43 
     44 	with_multiplier = 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; 
     62 	TYPE x, y, p, r, rx, ry;
     63 	size_t 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_multiplier)
     77 			rd = (params)[9];
     78 		memmove(stream->buf, stream->buf + stream->frame_size,
     79 			stream->ptr -= stream->frame_size);
     80 
     81 		x2 -= x1;
     82 		y2 -= y1;
     83 		norm = sqrt(x2 * x2 + y2 * y2);
     84 		x2 /= norm;
     85 		y2 /= norm;
     86 
     87 		for (iy = 0; iy < height; iy++) {
     88 			y = (TYPE)iy - y1;
     89 			for (ix = 0; ix < width; ix++) {
     90 				x = (TYPE)ix - x1;
     91 				p = x * x2 + y * y2;
     92 				rx = x - p * x2;
     93 				ry = y - p * y2;
     94 				r = sqrt(rx * rx + ry * ry) / rd;
     95 				p = abs(p);
     96 				x = MAX(p, r) / norm;
     97 				buf[ptr][0] = buf[ptr][1] = buf[ptr][2] = buf[ptr][3] = x;
     98 				if (++ptr == ELEMENTSOF(buf)) {
     99 					ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>");
    100 					ptr = 0;
    101 				}
    102 			}
    103 		}
    104 	}
    105 }
    106 
    107 #endif