Introduction
Introduction Statistics Contact Development Disclaimer Help
Add blind-apply-kernel - blind - suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log
Files
Refs
README
LICENSE
---
commit ebe2e88b44f46e59bdefef1eb585078d5fa6d4d4
parent 28635cabc72a60674c18c0e160fefdbd4af41734
Author: Mattias Andrée <[email protected]>
Date: Sat, 22 Jul 2017 19:33:54 +0200
Add blind-apply-kernel
Signed-off-by: Mattias Andrée <[email protected]>
Diffstat:
M Makefile | 1 +
M README | 6 ++++++
M TODO | 1 -
A man/blind-apply-kernel.1 | 69 ++++++++++++++++++++++++++++++
M man/blind-gauss-blur.1 | 4 +++-
M man/blind.7 | 6 ++++++
M src/blind-affine-colour.c | 2 ++
A src/blind-apply-kernel.c | 159 +++++++++++++++++++++++++++++…
8 files changed, 246 insertions(+), 2 deletions(-)
---
diff --git a/Makefile b/Makefile
@@ -4,6 +4,7 @@ include $(CONFIGFILE)
BIN =\
blind-affine-colour\
+ blind-apply-kernel\
blind-apply-palette\
blind-arithm\
blind-cat-cols\
diff --git a/README b/README
@@ -15,6 +15,12 @@ UTILITIES
blind-affine-colour(1)
Apply an affine transformation to the colours in a video
+ blind-apply-kernel(1)
+ Apply a convolution matrix to a video
+
+ blind-apply-palette(1)
+ Apply a colour palette to a video
+
blind-arithm(1)
Perform simple arithmetic on a video
diff --git a/TODO b/TODO
@@ -4,7 +4,6 @@ blind-primary-key replace a primary with transparency, -…
blind-colour-matrix create colour space conversion matrix
blind-apply-map remap pixels (distortion) using the X and Y val…
improve quality on downscaling (pixels' neighb…
-blind-apply-kernel apply a convolution matrix.
blind-find-frame a graphical tool for locating frames, should highlight…
play audio. Should support both regular videos…
finding key frames: ffprobe -show_frames (list…
diff --git a/man/blind-apply-kernel.1 b/man/blind-apply-kernel.1
@@ -0,0 +1,69 @@
+.TH BLIND-APPLY-KERNEL 1 blind
+.SH NAME
+blind-apply-kernel - Apply a convolution matrix to a video
+.SH SYNOPSIS
+.B blind-apply-kernel
+[-apPxy]
+.I kernel-stream
+.SH DESCRIPTION
+.B blind-apply-kernel
+reads a video from stdin and a convolution matrix video
+from
+.I kernel-stream
+and apply the convolution matrix in each frame the
+same frame in stdin, and prints the resulting video
+to stdout.
+.SH OPTIONS
+.TP
+.B -a
+Used to optimise performance if it is known that
+the video is opaque, and to ensure that the output
+video is opaque.
+.TP
+.B -p
+Each frame in
+.I kernel-stream
+shall contain one matrix per pixel in a frame in
+stdin. The width of
+.I kernel-stream
+shall be a multiple of the width of stdin, the width
+shall be the width of stdin multiplied by the width
+of the convolution matrix. The height of
+.I kernel-stream
+shall be a multiple of the height of stdin, the
+height shall be the height of stdin multiplied by the
+height of the convolution matrix.
+.TP
+.B -P
+Apply the convolution with first premultiplying
+the alpha channel.
+.TP
+.B -x
+When encountering the left or right edge of the video,
+wrap around to the opposite edge.
+.TP
+.B -y
+When encountering the upper or lower edge of the video,
+wrap around to the opposite edge.
+.SH REQUIREMENTS
+.B blind-apply-kernel
+requires enough free memory to load two full frames
+from stdin and one full frame from
+.I kernel-stream
+into memory. However, if
+.I -p
+is used, the height of
+.I kernel-stream
+divide by the height of stdin number of rows from
+.I kernel-stream
+rather than a full frame from
+.I kernel-stream
+is loaded into memory.
+A frame or row requires 32 bytes per pixel it contains.
+.SH SEE ALSO
+.BR blind (7),
+.BR blind-make-kernel (1),
+.BR blind-gauss-blur (1)
+.SH AUTHORS
+Mattias Andrée
+.RI < [email protected] >
diff --git a/man/blind-gauss-blur.1 b/man/blind-gauss-blur.1
@@ -79,7 +79,9 @@ memory. A frame requires 32 bytes per pixel it contains.
.SH SEE ALSO
.BR blind (7),
.BR blind-single-colour (1),
-.BR blind-time-blur (1)
+.BR blind-time-blur (1),
+.BR blind-make-kernel (1),
+.BR blind-apply-kernel (1)
.SH AUTHORS
Mattias Andrée
.RI < [email protected] >
diff --git a/man/blind.7 b/man/blind.7
@@ -22,6 +22,12 @@ first convert it with
.BR blind-affine-colour (1)
Apply an affine transformation to the colours in a video
.TP
+.BR blind-apply-kernel (1)
+Apply a convolution matrix to a video
+.TP
+.BR blind-apply-palette (1)
+Apply a colour palette to a video
+.TP
.BR blind-arithm (1)
Perform simple arithmetic on a video
.TP
diff --git a/src/blind-affine-colour.c b/src/blind-affine-colour.c
@@ -113,6 +113,8 @@ PROCESS(struct stream *colour, struct stream *matrix)
} while (eread_stream(colour, SIZE_MAX));
if (colour->ptr)
eprintf("%s: incomplete frame\n", colour->file);
+
+ free(mbuf);
}
#endif
diff --git a/src/blind-apply-kernel.c b/src/blind-apply-kernel.c
@@ -0,0 +1,159 @@
+/* See LICENSE file for copyright and license details. */
+#ifndef TYPE
+#include "common.h"
+
+USAGE("[-apPxy] kernel-stream")
+
+static int no_alpha = 0;
+static int dont_premultiply = 0;
+static int per_pixel = 0;
+static int wrap_x = 0;
+static int wrap_y = 0;
+static size_t kern_w;
+static size_t kern_h;
+
+#define FILE "blind-apply-kernel.c"
+#include "define-functions.h"
+
+int
+main(int argc, char *argv[])
+{
+ struct stream colour, kernel;
+ void (*process)(struct stream *colour, struct stream *kernel);
+ size_t tmp;
+
+ ARGBEGIN {
+ case 'a':
+ no_alpha = 1;
+ break;
+ case 'p':
+ per_pixel = 1;
+ break;
+ case 'P':
+ dont_premultiply = 1;
+ break;
+ case 'x':
+ wrap_x = 1;
+ break;
+ case 'y':
+ wrap_y = 1;
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ if (argc != 1)
+ usage();
+
+ eopen_stream(&colour, NULL);
+ eopen_stream(&kernel, argv[0]);
+
+ SELECT_PROCESS_FUNCTION(&colour);
+ if (colour.encoding != kernel.encoding || colour.n_chan != kernel.n_ch…
+ eprintf("videos use incompatible pixel formats");
+ if (per_pixel && !(kernel.width % colour.width || kernel.height % colo…
+ eprintf("-p is specified but the dimensions of kernel-stream "
+ "are not multiples of the dimensions of stdin.");
+
+ kern_w = per_pixel ? kernel.width / colour.width : kernel.width;
+ kern_h = per_pixel ? kernel.height / colour.height : kernel.height;
+
+ tmp = kernel.height, kernel.height = kern_h;
+ echeck_dimensions(&colour, WIDTH | HEIGHT, NULL);
+ echeck_dimensions(&kernel, WIDTH | HEIGHT, NULL);
+ kernel.height = tmp;
+
+ fprint_stream_head(stdout, &colour);
+ efflush(stdout, "<stdout>");
+ process(&colour, &kernel);
+ return 0;
+}
+
+#else
+
+static void
+PROCESS(struct stream *colour, struct stream *kernel)
+{
+ TYPE *out, *clr, *krn, *kern, *pix;
+ size_t i, x, y, n, x2, y2;
+ ssize_t cx, cy, xoff, yoff;
+
+ out = emalloc(colour->frame_size);
+ clr = emalloc(colour->frame_size);
+ krn = emalloc2(kern_h, kernel->row_size);
+
+ xoff = (ssize_t)(kern_w / 2);
+ yoff = (ssize_t)(kern_h / 2);
+
+ n = colour->width * colour->height * colour->n_chan;
+ while (eread_frame(colour, clr)) {
+ /* premultiply */
+ if (!no_alpha && !dont_premultiply) {
+ for (i = 0; i < n; i += 4) {
+ clr[i + 0] *= clr[i + 3];
+ clr[i + 1] *= clr[i + 3];
+ clr[i + 2] *= clr[i + 3];
+ }
+ }
+
+ /* apply kernel */
+ memset(out, 0, colour->frame_size);
+ pix = out;
+ for (y = 0; y < colour->height; y++) {
+ if ((!y || per_pixel) && !eread_segment(kernel, krn, k…
+ goto done;
+ for (x = 0; x < colour->width; x++, pix += colour->n_c…
+ kern = per_pixel ? (krn + x * kern_w * kernel-…
+ for (y2 = 0; y2 < kern_h; y2++, kern += kernel…
+ cy = (ssize_t)(y + y2) - yoff;
+ if (cy < 0 || (size_t)cy >= colour->he…
+ if (!wrap_y)
+ continue;
+ cy %= (ssize_t)(colour->height…
+ if (cy < 0)
+ cy += (ssize_t)(colour…
+ }
+ for (x2 = 0; x2 < kern_w; x2++) {
+ cx = (ssize_t)(x + x2) - xoff;
+ if (cx < 0 || (size_t)cx >= co…
+ if (!wrap_x)
+ continue;
+ cx %= (ssize_t)(colour…
+ if (cx < 0)
+ cx += (ssize_t…
+ }
+ for (i = 0; i < colour->n_chan…
+ pix[i] += kern[x2 * ke…
+ clr[((size_t…
+ }
+ }
+ }
+ }
+
+ /* unpremultiply */
+ if (!dont_premultiply) {
+ for (i = 0; i < n; i += 4) {
+ if (out[i + 3]) {
+ out[i + 0] /= out[i + 3];
+ out[i + 1] /= out[i + 3];
+ out[i + 2] /= out[i + 3];
+ }
+ }
+ }
+
+ /* ensure video is opaque if -a was used */
+ if (no_alpha)
+ for (i = 0; i < n; i += 4)
+ out[i + 3] = 1;
+
+ /* output video */
+ ewriteall(STDOUT_FILENO, out, colour->frame_size, "<stdout>");
+ }
+done:
+
+ free(out);
+ free(clr);
+ free(krn);
+}
+
+#endif
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.