blind

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

blind-extend.c (2504B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include "common.h"
      3 
      4 USAGE("[-l left] [-r right] [-a above] [-b below] [-t]")
      5 
      6 int
      7 main(int argc, char *argv[])
      8 {
      9 	struct stream stream;
     10 	char *buf, *image;
     11 	size_t m, imgw, imgh, rown;
     12 	size_t xoff, yoff, h, x, y;
     13 	size_t left = 0, right = 0, top = 0, bottom = 0;
     14 	int tile = 0;
     15 
     16 	ARGBEGIN {
     17 	case 'l':
     18 		left = etozu_flag('l', UARGF(), 0, SIZE_MAX);
     19 		break;
     20 	case 'r':
     21 		right = etozu_flag('r', UARGF(), 0, SIZE_MAX);
     22 		break;
     23 	case 'a':
     24 		top = etozu_flag('a', UARGF(), 0, SIZE_MAX);
     25 		break;
     26 	case 'b':
     27 		bottom = etozu_flag('b', UARGF(), 0, SIZE_MAX);
     28 		break;
     29 	case 't':
     30 		tile = 1;
     31 		break;
     32 	default:
     33 		usage();
     34 	} ARGEND;
     35 
     36 	if (argc)
     37 		usage();
     38 
     39 	eopen_stream(&stream, NULL);
     40 
     41 	echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
     42 	buf = emalloc(stream.frame_size);
     43 
     44 	if (stream.width > SIZE_MAX - left)
     45 		eprintf("<stdout>: output video is too wide\n");
     46 	imgw = stream.width + left;
     47 	if (imgw > SIZE_MAX - right)
     48 		eprintf("<stdout>: output video is too wide\n");
     49 	imgw += right;
     50 	if (stream.height > SIZE_MAX - top)
     51 		eprintf("<stdout>: output video is too tall\n");
     52 	imgh = stream.height + top;
     53 	if (imgh > SIZE_MAX - bottom)
     54 		eprintf("<stdout>: output video is too tall\n");
     55 	imgh += bottom;
     56 	echeck_dimensions_custom(imgw, imgh, 0, stream.pixel_size, "output", "<stdout>");
     57 	m = imgh * (imgw *= stream.pixel_size);
     58 	image = tile ? emalloc(m) : ecalloc(1, m);
     59 
     60 	stream.width += left + right;
     61 	h = stream.height += top + bottom;
     62 	fprint_stream_head(stdout, &stream);
     63 	efflush(stdout, "<stdout>");
     64 	stream.width -= left + right;
     65 	stream.height -= top + bottom;
     66 
     67 	left  *= stream.pixel_size;
     68 	right *= stream.pixel_size;
     69 	rown = stream.width * stream.pixel_size;
     70 
     71 	xoff = (rown          - left % rown)          % rown;
     72 	yoff = (stream.height - top  % stream.height) % stream.height;
     73 
     74 	while (eread_frame(&stream, buf)) {
     75 		if (!tile) {
     76 			for (y = 0; y < stream.height; y++)
     77 				memcpy(image + left + (y + top) * imgw, buf + y * rown, rown);
     78 		} else {
     79 			for (y = 0; y < stream.height; y++)
     80 				for (x = 0; x < imgw; x++)
     81 					image[x + (y + top) * imgw] = buf[(x + xoff) % rown + y * rown];
     82 			for (y = 0; y < top; y++)
     83 				memcpy(image + y * imgw, image + ((y + yoff) % stream.height + top) * imgw, imgw);
     84 			for (y = top + stream.height; y < h; y++)
     85 				memcpy(image + y * imgw, image + ((y + yoff) % stream.height + top) * imgw, imgw);
     86 		}
     87 		ewriteall(STDOUT_FILENO, image, m, "<stdout>");
     88 	}
     89 
     90 	free(buf);
     91 	free(image);
     92 	return 0;
     93 }