aboutsummaryrefslogtreecommitdiffstats
path: root/src/vu-rewrite-head.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2017-01-12 01:37:54 +0100
committerMattias Andrée <maandree@kth.se>2017-01-12 01:38:44 +0100
commitc8c0993707b0780cb362892b2f78decaabce5f72 (patch)
tree88b972b3ffafd31ffdeb0417499a896dd0700fd8 /src/vu-rewrite-head.c
parentFree all allocations at end + use calloc instead of memset (diff)
downloadblind-c8c0993707b0780cb362892b2f78decaabce5f72.tar.gz
blind-c8c0993707b0780cb362892b2f78decaabce5f72.tar.bz2
blind-c8c0993707b0780cb362892b2f78decaabce5f72.tar.xz
Add vu-rewrite-head
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r--src/vu-rewrite-head.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/src/vu-rewrite-head.c b/src/vu-rewrite-head.c
new file mode 100644
index 0000000..e7663c8
--- /dev/null
+++ b/src/vu-rewrite-head.c
@@ -0,0 +1,127 @@
+/* See LICENSE file for copyright and license details. */
+#include "stream.h"
+#include "util.h"
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <inttypes.h>
+#include <string.h>
+#include <unistd.h>
+
+USAGE("[-h] file [(frames | 'auto') [(width | 'same') (height | 'same') [format | 'same']]]")
+
+static void
+rewrite(struct stream *stream, int frames_auto)
+{
+ char head[3 * sizeof(size_t) + 4 + sizeof(stream->pixfmt) + 6];
+ ssize_t headlen;
+ size_t frame_size, frame_count, length;
+ struct stat st;
+ char *data;
+
+ echeck_frame_size(stream->width, stream->height, stream->pixel_size, 0, stream->file);
+ frame_size = stream->width * stream->height * stream->pixel_size;
+
+ if (fstat(stream->fd, &st))
+ eprintf("fstat %s:", stream->file);
+ if (!S_ISREG(st.st_mode))
+ eprintf("%s: not a regular file\n", stream->file);
+
+ frame_count = (size_t)(st.st_size) / frame_size;
+ if (frame_count * frame_size != (size_t)(st.st_size))
+ eprintf("%s: given the select width and height, "
+ "the file has an incomplete frame\n", stream->file);
+ if (frames_auto)
+ stream->frames = frame_count;
+ else if (stream->frames != frame_count)
+ eprintf("%s: frame count mismatch\n", stream->file);
+
+ sprintf(head, "%zu %zu %zu %s\n%cuivf%zn",
+ stream->frames, stream->width, stream->height, stream->pixfmt, 0, &headlen);
+
+ length = stream->frames * frame_size;
+ if (length > (size_t)SSIZE_MAX || headlen > (size_t)SSIZE_MAX - length)
+ eprintf("%s: video is too long\n", stream->file);
+
+ if (headlen > stream->headlen)
+ if (ftruncate(stream->fd, length + headlen))
+ eprintf("ftruncate %s:", stream->file);
+
+ data = mmap(0, length + (size_t)headlen, PROT_READ | PROT_WRITE, MAP_PRIVATE, stream->fd, 0);
+ if (headlen != stream->headlen)
+ memmove(data + headlen, data + stream->headlen, length);
+ memcpy(data, head, (size_t)headlen);
+ munmap(data, length + (size_t)headlen);
+
+ if (headlen < stream->headlen)
+ if (ftruncate(stream->fd, length + headlen))
+ eprintf("ftruncate %s:", stream->file);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct stream stream;
+ int headless = 0, frames_auto = 0;
+
+ ARGBEGIN {
+ case 'h':
+ headless = 1;
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+
+ if (headless) {
+ if (argc != 5)
+ eprintf("all positional arguments are mandatory unless -h is used\n");
+ } else if (argc != 1 || argc != 2 || argc != 4 || argc != 5) {
+ usage();
+ }
+
+
+ memset(&stream, 0, sizeof(stream));
+ stream.file = argv[0];
+ stream.fd = eopen(stream.file, O_RDWR);
+ if (!headless)
+ einit_stream(&stream);
+
+
+ if (argc < 2 || !strcmp(argv[1], "auto"))
+ frames_auto = 1;
+ else
+ stream.frames = etozu_arg("the frame count", argv[1], 0, SIZE_MAX);
+
+ if (argc < 4);
+ else if (strcmp(argv[2], "same"))
+ stream.width = etozu_arg("the width", argv[2], 1, SIZE_MAX);
+ else if (headless)
+ eprintf("cannot use both 'same' and -h\n");
+
+ if (argc < 4);
+ else if (strcmp(argv[3], "same"))
+ stream.height = etozu_arg("the height", argv[3], 1, SIZE_MAX);
+ else if (headless)
+ eprintf("cannot use both 'same' and -h\n");
+
+ if (argc < 5);
+ else if (strcmp(argv[4], "same")) {
+ if (strlen(argv[4]) >= sizeof(stream.pixfmt))
+ eprintf("choosen pixel format is unsupported\n");
+ strcpy(stream.pixfmt, argv[5]);
+ if (set_pixel_size(&stream))
+ eprintf("choosen pixel format is unsupported\n");
+ } else if (headless) {
+ eprintf("cannot use both 'same' and -h\n");
+ } else if (argc > 1) {
+ usage();
+ }
+
+
+ rewrite(&stream, frames_auto);
+ close(stream.fd);
+ return 0;
+}