blind

suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log | Files | Refs | README | 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