blind-repeat.c - blind - suckless command-line video editing utility
(HTM) git clone git://git.suckless.org/blind
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) 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 }