blind-rewrite-head.c - blind - suckless command-line video editing utility | |
git clone git://git.suckless.org/blind | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
blind-rewrite-head.c (3241B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include "common.h" | |
3 | |
4 USAGE("[-h] file [(frames | 'auto') [(width | 'same') (height | 'same') … | |
5 | |
6 static void | |
7 rewrite(struct stream *stream, int frames_auto) | |
8 { | |
9 char head[STREAM_HEAD_MAX]; | |
10 ssize_t headlen; | |
11 size_t frame_count, length; | |
12 struct stat st; | |
13 char *data; | |
14 | |
15 echeck_dimensions(stream, WIDTH | HEIGHT, NULL); | |
16 | |
17 if (fstat(stream->fd, &st)) | |
18 eprintf("fstat %s:", stream->file); | |
19 if (!S_ISREG(st.st_mode)) | |
20 eprintf("%s: not a regular file\n", stream->file); | |
21 | |
22 frame_count = (size_t)(st.st_size) / stream->frame_size; | |
23 if (frame_count * stream->frame_size != (size_t)(st.st_size) - s… | |
24 eprintf("%s: given the select width and height, " | |
25 "the file has an incomplete frame\n", stream->fi… | |
26 if (frames_auto) | |
27 stream->frames = frame_count; | |
28 else if (stream->frames != frame_count) | |
29 eprintf("%s: frame count mismatch\n", stream->file); | |
30 | |
31 SPRINTF_HEAD_ZN(head, stream->frames, stream->width, stream->hei… | |
32 | |
33 length = stream->frames * stream->frame_size; | |
34 if (length > (size_t)SSIZE_MAX || (size_t)headlen > (size_t)SSIZ… | |
35 eprintf("%s: video is too long\n", stream->file); | |
36 | |
37 if ((size_t)headlen > stream->headlen) | |
38 if (ftruncate(stream->fd, (off_t)length + (off_t)headlen… | |
39 eprintf("ftruncate %s:", stream->file); | |
40 | |
41 data = mmap(0, length + (size_t)headlen, PROT_READ | PROT_WRITE,… | |
42 if (data == MAP_FAILED) | |
43 eprintf("mmap %s:", stream->file); | |
44 if ((size_t)headlen != stream->headlen) | |
45 memmove(data + headlen, data + stream->headlen, length); | |
46 memcpy(data, head, (size_t)headlen); | |
47 munmap(data, length + (size_t)headlen); | |
48 | |
49 if ((size_t)headlen < stream->headlen) | |
50 if (ftruncate(stream->fd, (off_t)length + (off_t)headlen… | |
51 eprintf("ftruncate %s:", stream->file); | |
52 } | |
53 | |
54 int | |
55 main(int argc, char *argv[]) | |
56 { | |
57 struct stream stream; | |
58 int headless = 0, frames_auto = 0; | |
59 | |
60 ARGBEGIN { | |
61 case 'h': | |
62 headless = 1; | |
63 break; | |
64 default: | |
65 usage(); | |
66 } ARGEND; | |
67 | |
68 if (headless) { | |
69 if (argc != 5) | |
70 eprintf("all positional arguments are mandatory … | |
71 } else if (argc != 1 && argc != 2 && argc != 4 && argc != 5) { | |
72 usage(); | |
73 } | |
74 | |
75 memset(&stream, 0, sizeof(stream)); | |
76 stream.file = argv[0]; | |
77 stream.fd = eopen(stream.file, O_RDWR); | |
78 if (!headless) | |
79 einit_stream(&stream); | |
80 | |
81 if (argc < 2 || !strcmp(argv[1], "auto")) | |
82 frames_auto = 1; | |
83 else | |
84 stream.frames = etozu_arg("the frame count", argv[1], 0,… | |
85 | |
86 if (argc < 4); | |
87 else if (strcmp(argv[2], "same")) | |
88 stream.width = etozu_arg("the width", argv[2], 1, SIZE_… | |
89 else if (headless) | |
90 eprintf("cannot use both 'same' and -h\n"); | |
91 | |
92 if (argc < 4); | |
93 else if (strcmp(argv[3], "same")) | |
94 stream.height = etozu_arg("the height", argv[3], 1, SIZE… | |
95 else if (headless) | |
96 eprintf("cannot use both 'same' and -h\n"); | |
97 | |
98 if (argc < 5); | |
99 else if (strcmp(argv[4], "same")) { | |
100 if (strlen(argv[4]) >= sizeof(stream.pixfmt)) | |
101 eprintf("choosen pixel format is unsupported\n"); | |
102 if (set_pixel_format(&stream, argv[5])) | |
103 eprintf("choosen pixel format is unsupported\n"); | |
104 } else if (headless) { | |
105 eprintf("cannot use both 'same' and -h\n"); | |
106 } | |
107 | |
108 rewrite(&stream, frames_auto); | |
109 close(stream.fd); | |
110 return 0; | |
111 } |