blind-reverse.c - blind - suckless command-line video editing utility | |
git clone git://git.suckless.org/blind | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
blind-reverse.c (2377B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include "common.h" | |
3 | |
4 USAGE("[-i] file") | |
5 | |
6 static void | |
7 to_stdout(struct stream *stream) | |
8 { | |
9 size_t ptr, end, n; | |
10 char buf[BUFSIZ]; | |
11 | |
12 while (stream->frames--) { | |
13 ptr = stream->frames * stream->frame_size + stream->head… | |
14 end = ptr + stream->frame_size; | |
15 while (ptr < end) { | |
16 if (!(n = epread(stream->fd, buf, MIN(sizeof(buf… | |
17 (off_t)ptr, stream->file))) | |
18 eprintf("%s: file is shorter than expect… | |
19 ptr += n; | |
20 ewriteall(STDOUT_FILENO, buf, n, "<stdout>"); | |
21 } | |
22 } | |
23 } | |
24 | |
25 static void | |
26 elseek_set(int fd, off_t offset, const char *fname) | |
27 { | |
28 off_t r = elseek(fd, offset, SEEK_SET, fname); | |
29 if (r != offset) | |
30 eprintf("%s: file is shorter than expected\n", fname); | |
31 } | |
32 | |
33 static void | |
34 epread_frame(struct stream *stream, char *buf, off_t off) | |
35 { | |
36 stream->ptr = stream->xptr = 0; | |
37 elseek_set(stream->fd, off, stream->file); | |
38 eread_frame(stream, buf); | |
39 } | |
40 | |
41 static void | |
42 epwrite_frame(struct stream *stream, char *buf, off_t off) | |
43 { | |
44 elseek_set(stream->fd, off, stream->file); | |
45 ewriteall(stream->fd, buf, stream->frame_size, stream->file); | |
46 } | |
47 | |
48 static void | |
49 in_place(struct stream *stream) | |
50 { | |
51 size_t f, fm = stream->frames - 1; | |
52 off_t pa, pb; | |
53 char *bufa, *bufb; | |
54 | |
55 bufa = emalloc(stream->frame_size); | |
56 bufb = emalloc(stream->frame_size); | |
57 | |
58 for (f = 0; f < stream->frames >> 1; f++) { | |
59 pa = (off_t)f * (off_t)(stream->frame_size) + (of… | |
60 pb = (off_t)(fm - f) * (off_t)(stream->frame_size) + (of… | |
61 | |
62 epread_frame(stream, bufa, pa); | |
63 epread_frame(stream, bufb, pb); | |
64 | |
65 epwrite_frame(stream, bufa, pb); | |
66 epwrite_frame(stream, bufb, pa); | |
67 } | |
68 | |
69 free(bufa); | |
70 free(bufb); | |
71 } | |
72 | |
73 int | |
74 main(int argc, char *argv[]) | |
75 { | |
76 struct stream stream; | |
77 int inplace = 0; | |
78 | |
79 ARGBEGIN { | |
80 case 'i': | |
81 inplace = 1; | |
82 break; | |
83 default: | |
84 usage(); | |
85 } ARGEND; | |
86 | |
87 if (argc != 1) | |
88 usage(); | |
89 | |
90 stream.file = argv[0]; | |
91 stream.fd = eopen(stream.file, inplace ? O_RDWR : O_RDONLY); | |
92 einit_stream(&stream); | |
93 if (!inplace) { | |
94 fprint_stream_head(stdout, &stream); | |
95 efflush(stdout, "<stdout>"); | |
96 } | |
97 echeck_dimensions(&stream, WIDTH | HEIGHT, NULL); | |
98 if (stream.frames * stream.frame_size > (size_t)SSIZE_MAX - stre… | |
99 eprintf("%s: video is too large\n", stream.file); | |
100 | |
101 fadvise_random(stream.fd, 0, 0); | |
102 | |
103 (inplace ? in_place : to_stdout)(&stream); | |
104 close(stream.fd); | |
105 return 0; | |
106 } |