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 }