Introduction
Introduction Statistics Contact Development Disclaimer Help
Add blind-peek-head - blind - suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log
Files
Refs
README
LICENSE
---
commit 23100155b5d0ecbf95a8d1c4fa8d02557b69de94
parent 6ca85b3362761f24f8913314bf5cfdfa35241fef
Author: Mattias Andrée <[email protected]>
Date: Wed, 23 Aug 2017 00:39:26 +0200
Add blind-peek-head
Signed-off-by: Mattias Andrée <[email protected]>
Diffstat:
M Makefile | 3 ++-
M README | 3 +++
M config.mk | 8 ++++----
A man/blind-peek-head.1 | 28 ++++++++++++++++++++++++++++
M man/blind-read-head.1 | 1 +
M man/blind.7 | 3 +++
A src/blind-peek-head.c | 152 +++++++++++++++++++++++++++++…
7 files changed, 193 insertions(+), 5 deletions(-)
---
diff --git a/Makefile b/Makefile
@@ -60,8 +60,9 @@ BIN =\
blind-multiply-matrices\
blind-next-frame\
blind-norm\
- blind-quaternion-product\
+ blind-peek-head\
blind-premultiply\
+ blind-quaternion-product\
blind-radial-gradient\
blind-read-head\
blind-rectangle-tessellation\
diff --git a/README b/README
@@ -177,6 +177,9 @@ UTILITIES
blind-norm(1)
Calculate the norm of colours in a video
+ blind-peek-head
+ Peeks the head from a video
+
blind-premultiply(1)
Premultiply the alpha channel of a video
diff --git a/config.mk b/config.mk
@@ -13,9 +13,9 @@ KORN_SHELL = bash
# Commands
LN = ln -s
-# You may want to remove -DHAVE_PRCTL, -DHAVE_EPOLL, and
-# -DHAVE_SENDFILE from CPPFLAGS if you are not using Linux.
+# You may want to remove -DHAVE_PRCTL, -DHAVE_EPOLL, -DHAVE_TEE,
+# and -DHAVE_SENDFILE from CPPFLAGS if you are not using Linux.
CFLAGS = -std=c11 -Wall -pedantic -O2
-CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_FILE_OFFSET_…
- -DHAVE_PRCTL -DHAVE_EPOLL -DHAVE_SENDFILE
+CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE \
+ -D_FILE_OFFSET_BITS=64 -DHAVE_PRCTL -DHAVE_EPOLL -DHAVE_TEE -DHAVE_…
LDFLAGS = -lm -s
diff --git a/man/blind-peek-head.1 b/man/blind-peek-head.1
@@ -0,0 +1,28 @@
+.TH BLIND-PEEK-HEAD 1 blind
+.SH NAME
+blind-peek-head - Peeks the head from a video
+.SH SYNOPSIS
+.B blind-peek-head
+.SH DESCRIPTION
+.B blind-peek-head
+peeks the head a video from stdin, and
+prints it, without the magic number, to stdout.
+The output will contain: the number of frames,
+<space>, the width, <space>, the height, <space>,
+and the pixel format. The output is text, and
+thus ends with a <newline>. The state of stdin
+will remain unchanged.
+.SH NOTES
+.B blind-peek-head
+requires that stdin is a socket, a regular file,
+or a (on Linux only) a pipe. Direct pipes and
+datagram sockets are supported but require that
+the entire head must be written in one write.
+.SH SEE ALSO
+.BR blind (7),
+.BR blind-read-head (1),
+.BR blind-write-head (1),
+.BR blind-next-frame (1)
+.SH AUTHORS
+Mattias Andrée
+.RI < [email protected] >
diff --git a/man/blind-read-head.1 b/man/blind-read-head.1
@@ -18,6 +18,7 @@ can be used to get the first, and
any following, frame from stdin.
.SH SEE ALSO
.BR blind (7),
+.BR blind-peek-head (1),
.BR blind-write-head (1),
.BR blind-next-frame (1)
.SH AUTHORS
diff --git a/man/blind.7 b/man/blind.7
@@ -195,6 +195,9 @@ Extracts the next frame from a video
.BR blind-norm (1)
Calculate the norm of colours in a video
.TP
+.BR blind-peek-head (1)
+Peeks the head from a video
+.TP
.BR blind-premultiply (1)
Premultiply the alpha channel of a video
.TP
diff --git a/src/blind-peek-head.c b/src/blind-peek-head.c
@@ -0,0 +1,152 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+USAGE("")
+
+static ssize_t
+peek_socket(char *buf, size_t n)
+{
+ ssize_t r = recv(STDIN_FILENO, buf, n, MSG_PEEK);
+ if (r < 0 && errno != ENOTSOCK)
+ eprintf("recv <stdin>:");
+ return r;
+}
+
+static ssize_t
+peek_regular(char *buf, size_t n)
+{
+ ssize_t r;
+ off_t pos = lseek(STDIN_FILENO, 0, SEEK_CUR);
+ if (pos < 0) {
+ if (errno != ESPIPE)
+ eprintf("lseek <stdin>:");
+ return -1;
+ }
+ r = pread(STDIN_FILENO, buf, n, pos);
+ if (r < 0 && errno != ESPIPE)
+ eprintf("pread <stdin>:");
+ return r;
+}
+
+#if defined(HAVE_TEE)
+static ssize_t
+peek_pipe(char *buf, size_t n)
+{
+ int rw[2];
+ ssize_t m;
+ size_t p;
+ if (pipe(rw))
+ eprintf("pipe");
+ m = tee(STDIN_FILENO, rw[1], n, 0);
+ if (m < 0) {
+ if (errno != EINVAL)
+ eprintf("tee <stdin>:");
+ return -1;
+ }
+ close(rw[1]);
+ p = ereadall(rw[0], buf, (size_t)m, "<pipe>");
+ close(rw[0]);
+ return (ssize_t)p;
+}
+#endif
+
+static size_t
+peek(char *buf, size_t n)
+{
+ static int method = 0;
+ ssize_t r;
+ switch (method) {
+ case 0:
+ if ((r = peek_socket(buf, n)) >= 0)
+ return (size_t)r;
+ method++;
+ /* fall-through */
+ case 1:
+ if ((r = peek_regular(buf, n)) >= 0)
+ return (size_t)r;
+ method++;
+#if defined(HAVE_TEE)
+ /* fall-through */
+ default:
+ if ((r = peek_pipe(buf, n)) >= 0)
+ return (size_t)r;
+ eprintf("can only peek pipes, sockets, and regular files\n");
+#else
+ eprintf("can only peek sockets and regular files\n");
+#endif
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ char buf[STREAM_HEAD_MAX], *p;
+ char magic[] = {'\0', 'u', 'i', 'v', 'f'};
+ size_t i, len = 0, last_len;
+#if defined(HAVE_EPOLL)
+ struct epoll_event ev;
+ int epfd, epr = 0;
+#endif
+
+ UNOFLAGS(argc);
+
+#if defined(HAVE_EPOLL)
+ epfd = epoll_create1(0);
+ if (epfd < 0)
+ eprintf("epoll_create1:");
+
+ memset(&ev, 0, sizeof(ev));
+ ev.events = EPOLLIN | EPOLLRDHUP | EPOLLET;
+ if (epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev))
+ eprintf("epoll_ctl EPOLL_CTL_ADD:");
+
+ do {
+ last_len = len;
+ len = peek(buf, sizeof(buf));
+ p = memchr(buf, '\n', len);
+ if (p && len >= (size_t)(++p - buf) + ELEMENTSOF(magic))
+ goto ready;
+ } while (len > last_len && (epr = epoll_wait(epfd, &ev, 1, -1)) >= 0);
+ if (epr < 0)
+ eprintf("epoll_wait:");
+#else
+ goto beginning;
+ do {
+ usleep(50000);
+ beginning:
+ last_len = len;
+ len = peek(buf, n);
+ p = memchr(buf, '\n', len);
+ if (p && len >= (size_t)(++p - buf) + ELEMENTSOF(magic))
+ goto ready;
+ } while (len > last_len);
+#endif
+ eprintf("could not read entire head\n");
+
+ready:
+ len = (size_t)(p - buf);
+ for (i = 0; i < ELEMENTSOF(magic); i++)
+ if (p[i] != magic[i])
+ goto bad_format;
+ p = buf;
+ for (i = 0; i < 3; i++) {
+ if (!isdigit(*p))
+ goto bad_format;
+ while (isdigit(*p)) p++;
+ if (*p++ != ' ')
+ goto bad_format;
+ }
+ while (isalnum(*p) || *p == ' ') {
+ if (p[0] == ' ' && p[-1] == ' ')
+ goto bad_format;
+ p++;
+ }
+ if (p[-1] == ' ' || p[0] != '\n')
+ goto bad_format;
+
+ ewriteall(STDOUT_FILENO, buf, len, "<stdout>");
+ return 0;
+
+bad_format:
+ eprintf("<stdin>: file format not supported\n");
+}
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.