blind

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

blind-repeat.c (2419B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include "common.h"
      3 
      4 USAGE("([-f] count | 'inf') [file]")
      5 
      6 static size_t count = 0;
      7 static int inf;
      8 static struct stream stream;
      9 
     10 static int
     11 repeat_regular_file(void)
     12 {
     13 	stream.ptr = 0;
     14 	while (inf || count--) {
     15 		fadvise_sequential(stream.fd, (off_t)(stream.headlen), 0);
     16 		elseek(stream.fd, (off_t)(stream.headlen), SEEK_SET, stream.file);
     17 		if (esend_stream(&stream, STDOUT_FILENO, NULL))
     18 			return -1;
     19 	}
     20 	return 0;
     21 }
     22 
     23 static int
     24 repeat_regular_file_framewise(void)
     25 {
     26 	size_t i;
     27 	off_t off = (off_t)(stream.headlen);
     28 	stream.ptr = 0;
     29 	echeck_dimensions(&stream, WIDTH | HEIGHT | LENGTH, "input");
     30 	for (;; off += (off_t)(stream.frame_size)) {
     31 		for (i = 0; i < count; i++) {
     32 			elseek(stream.fd, off, SEEK_SET, stream.file);
     33 			if (!esend_frames(&stream, STDOUT_FILENO, 1, "<stdout>"))
     34 				return 0;
     35 		}
     36 	}
     37 }
     38 
     39 static int
     40 repeat_stdin(void)
     41 {
     42 	size_t ptr = stream.ptr;
     43 	size_t size = MAX(ptr, BUFSIZ);
     44 	char *buf = memcpy(emalloc(size), stream.buf, ptr);
     45 	egetfile(STDIN_FILENO, &buf, &ptr, &size, "<stdout>");
     46 	while (inf || count--)
     47 		if (writeall(STDOUT_FILENO, buf, ptr))
     48 			return free(buf), -1;
     49 	return free(buf), 0;
     50 }
     51 
     52 static int
     53 repeat_stdin_framewise(void)
     54 {
     55 	char *buf;
     56 	size_t i;
     57 	echeck_dimensions(&stream, WIDTH | HEIGHT, "input");
     58 	buf = emalloc(stream.frame_size);
     59 	while (eread_frame(&stream, buf))
     60 		for (i = 0; i < count; i++)
     61 			if (writeall(STDOUT_FILENO, buf, stream.frame_size))
     62 				return free(buf), -1;
     63 	return free(buf), 0;
     64 }
     65 
     66 int
     67 main(int argc, char *argv[])
     68 {
     69 	int framewise = 0;
     70 
     71 	ARGBEGIN {
     72 	case 'f':
     73 		framewise = 1;
     74 		break;
     75 	default:
     76 		usage();
     77 	} ARGEND;
     78 
     79 	if (argc < 1 || argc > 2)
     80 		usage();
     81 
     82 	if ((inf = !strcmp(argv[0], "inf"))) {
     83 		if (framewise)
     84 			usage();
     85 		einf_check_fd(STDOUT_FILENO, "<stdout>");
     86 	} else {
     87 		count = etozu_arg("the count", argv[0], 0, SIZE_MAX);
     88 	}
     89 
     90 	if (argv[1] && !strcmp(argv[1], "-"))
     91 		argv[1] = NULL;
     92 
     93 	eopen_stream(&stream, argv[1]);
     94 	if (stream.frames && count > SIZE_MAX / stream.frames)
     95 		eprintf("%s: video is too long\n", stream.file);
     96 	stream.frames *= count;
     97 	fprint_stream_head(stdout, &stream);
     98 	efflush(stdout, "<stdout>");
     99 
    100 	if (!argv[1]
    101 	    ? (framewise ? repeat_stdin_framewise()       : repeat_stdin())
    102 	    : (framewise ? repeat_regular_file_framewise(): repeat_regular_file()))
    103 		if (!inf || errno != EPIPE)
    104 			eprintf("write <stdout>:");
    105 
    106 	close(stream.fd);
    107 	return 0;
    108 }