Add blind-affine-colour and blind-split-chans - blind - suckless command-line v… | |
git clone git://git.suckless.org/blind | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit fa20f84e2d12bf9998591ce4e464180586d957ff | |
parent 0a034f2bd5a44c3cc0c033eacc940bb3bf73662c | |
Author: Mattias Andrée <[email protected]> | |
Date: Thu, 20 Jul 2017 20:03:52 +0200 | |
Add blind-affine-colour and blind-split-chans | |
Signed-off-by: Mattias Andrée <[email protected]> | |
Diffstat: | |
M Makefile | 2 ++ | |
M README | 6 ++++++ | |
M TODO | 25 ++++++++++++------------- | |
A man/blind-affine-colour.1 | 71 +++++++++++++++++++++++++++++… | |
M man/blind-arithm.1 | 3 ++- | |
M man/blind-invert-matrix.1 | 3 ++- | |
M man/blind-multiply-matrices.1 | 3 ++- | |
M man/blind-rewrite-head.1 | 3 ++- | |
A man/blind-split-chans.1 | 47 +++++++++++++++++++++++++++++… | |
M man/blind.7 | 6 ++++++ | |
A src/blind-affine-colour.c | 118 +++++++++++++++++++++++++++++… | |
A src/blind-split-chans.c | 65 +++++++++++++++++++++++++++++… | |
12 files changed, 335 insertions(+), 17 deletions(-) | |
--- | |
diff --git a/Makefile b/Makefile | |
@@ -3,6 +3,7 @@ include $(CONFIGFILE) | |
BIN =\ | |
+ blind-affine-colour\ | |
blind-apply-palette\ | |
blind-arithm\ | |
blind-cat-cols\ | |
@@ -76,6 +77,7 @@ BIN =\ | |
blind-spectrum\ | |
blind-spiral-gradient\ | |
blind-split\ | |
+ blind-split-chans\ | |
blind-split-cols\ | |
blind-split-rows\ | |
blind-square-gradient\ | |
diff --git a/README b/README | |
@@ -12,6 +12,9 @@ DESCRIPTION | |
storing the video without first convert it with blind-to-video(1). | |
UTILITIES | |
+ blind-affine-colour(1) | |
+ Apply an affine transformation to the colours in a video | |
+ | |
blind-arithm(1) | |
Perform simple arithmetic on a video | |
@@ -234,6 +237,9 @@ UTILITIES | |
blind-split(1) | |
Split a video, by frame, into multiple videos | |
+ blind-split-chans(1) | |
+ Split colour channels into separate videos | |
+ | |
blind-split-cols(1) | |
Split a video vertically into multiple videos | |
diff --git a/TODO b/TODO | |
@@ -1,22 +1,17 @@ | |
Fix blind-from-named without command | |
-blind-transform affine transformation by matrix multiplication,… | |
- improve quality on downscaling (pixels' neighb… | |
-blind-primary-key replace a primary with transparency, -g for greyscale… | |
-blind-primaries given three selectable primaries split the vide… | |
- only one primary active. | |
-blind-apply-map remap pixels (distortion) using the X and Y val… | |
- improve quality on downscaling (pixels' neighb… | |
+blind-transform affine transformation by matrix multiplication,… | |
+ improve quality on downscaling (pixels' neighb… | |
+blind-primary-key replace a primary with transparency, -g for greyscale… | |
+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… | |
+ play audio. Should support both regular videos… | |
finding key frames: ffprobe -show_frames (list… | |
-blind-affine-colour apply an affine transformation to the colour of eac… | |
- -a for ignoring the alpha channel, | |
- -l for linear transformation, | |
- -p for transforming each pixel with their own … | |
blind-invert-chroma invert the chroma | |
-blind-from-sent convert a sent presentation to a one-frame-per-… | |
+blind-from-sent convert a sent presentation to a one-frame-per-… | |
blind-kirsch https://en.wikipedia.org/wiki/Kirsch_operator | |
blind-gaussian-noise https://en.wikipedia.org/wiki/Gaussian_noise | |
@@ -43,6 +38,10 @@ blind-mean mean of multiple streams | |
https://en.wikipedia.org/wiki/Stolarsky_mean | |
blind-temporal-arithm blind-arithm but over all frames in a video inste… | |
blind-apply-icc apply ICC profile to video | |
+blind-convex-gradient create a gradient in the shape of a convex lens | |
+blind-concave-gradient create a gradient in the shape of a concave lens | |
+ (convexo-concave gradient is not necessary is blind-co… | |
+ or blind-concave-gradient can be combined with blind-… | |
blind-from-video: add options to: | |
* just run ffmpeg just print the output | |
diff --git a/man/blind-affine-colour.1 b/man/blind-affine-colour.1 | |
@@ -0,0 +1,71 @@ | |
+.TH BLIND-AFFINE-COLOUR 1 blind | |
+.SH NAME | |
+blind-affine-colour - Apply an affine transformation to the colours in a video | |
+.SH SYNOPSIS | |
+.B blind-affine-colour | |
+[-alp] | |
+.I matrix-stream | |
+.SH DESCRIPTION | |
+.B blind-affine-colour | |
+reads a video from stdin and a matrix video from | |
+.I matrix-stream | |
+and multiplies colours from stdin with matrices from | |
+.I matrix-stream | |
+and prints the resulting video to stdout. | |
+.P | |
+Each frame in | |
+.I matrix-stream | |
+is a matrix and shall have the width and height 5. | |
+Each pixel in a frame is a cell in the matrix, | |
+the pixels luma is multiples by its alpha value | |
+to determine the value of the matrix cell. | |
+.SH OPTIONS | |
+.TP | |
+.B -a | |
+The width and height of the matrix shall be 4 | |
+instead of 5 (reduced by 1) and the alpha values | |
+of the pixels shall not be modified. | |
+.TP | |
+.B -l | |
+The width and height of the matrix shall be 4 | |
+instead of 5 (reduced by 1) making the transformation | |
+linear instead of affine. | |
+.TP | |
+.B -p | |
+Each frame in | |
+.I matrix-stream | |
+shall contain one matrix per pixel in a frame in | |
+stdin. The video in | |
+.I matrix-stream | |
+shall be 5, 4, or 3, depending on whether | |
+.B -a | |
+and | |
+.B -l | |
+are specified, times are wide and tall as the | |
+video in stdin. | |
+.SH NOTES | |
+If both | |
+.B -a | |
+and | |
+.B -l | |
+are specified, the matrices shall have the | |
+width and height 3 instead of 5. | |
+.SH REQUIREMENTS | |
+.B blind-affine-colour | |
+requires enough free memory to load 5, 4, or 3, | |
+depending on whether | |
+.B -a | |
+and | |
+.B -l | |
+are specified, full rows from | |
+.I matrix-stream | |
+into memory. A frame requires 32 bytes per pixel | |
+it contains. | |
+.SH SEE ALSO | |
+.BR blind (7), | |
+.BR blind-arithm (1), | |
+.BR blind-invert-matrix (1), | |
+.BR blind-multiply-matrice (1) | |
+.SH AUTHORS | |
+Mattias Andrée | |
+.RI < [email protected] > | |
diff --git a/man/blind-arithm.1 b/man/blind-arithm.1 | |
@@ -90,7 +90,8 @@ Do not modify the Z channel (the third channel). | |
.BR blind-set-alpha (1), | |
.BR blind-set-luma (1), | |
.BR blind-invert-luma (1), | |
-.BR blind-set-saturation (1) | |
+.BR blind-set-saturation (1), | |
+.BR blind-affine-colour (1) | |
.SH AUTHORS | |
Mattias Andrée | |
.RI < [email protected] > | |
diff --git a/man/blind-invert-matrix.1 b/man/blind-invert-matrix.1 | |
@@ -29,7 +29,8 @@ are identical. | |
.BR blind-flop (1), | |
.BR blind-rotate-90 (1), | |
.BR blind-rotate-180 (1), | |
-.BR blind-rotate-270 (1) | |
+.BR blind-rotate-270 (1), | |
+.BR blind-rewrite-head (1) | |
.SH AUTHORS | |
Mattias Andrée | |
.RI < [email protected] > | |
diff --git a/man/blind-multiply-matrices.1 b/man/blind-multiply-matrices.1 | |
@@ -44,7 +44,8 @@ in reverse order. | |
.BR blind-flop (1), | |
.BR blind-rotate-90 (1), | |
.BR blind-rotate-180 (1), | |
-.BR blind-rotate-270 (1) | |
+.BR blind-rotate-270 (1), | |
+.BR blind-rewrite-head (1) | |
.SH AUTHORS | |
Mattias Andrée | |
.RI < [email protected] > | |
diff --git a/man/blind-rewrite-head.1 b/man/blind-rewrite-head.1 | |
@@ -72,7 +72,8 @@ two copies of on disc. | |
.BR blind-from-video (1), | |
.BR blind-split (1), | |
.BR blind-read-head (1), | |
-.BR blind-write-head (1) | |
+.BR blind-write-head (1), | |
+.BR blind-transpose (1) | |
.SH AUTHORS | |
Mattias Andrée | |
.RI < [email protected] > | |
diff --git a/man/blind-split-chans.1 b/man/blind-split-chans.1 | |
@@ -0,0 +1,47 @@ | |
+.TH BLIND-SPLIT-CHANS 1 blind | |
+.SH NAME | |
+blind-split-chans - Split colour channels into separate videos | |
+.SH SYNOPSIS | |
+.B blind-split-chans | |
+.I X-file | |
+.I Y-file | |
+.I Z-file | |
+.RI [ alpha-file ] | |
+.SH DESCRIPTION | |
+.B blind-split-chans | |
+reads a video from stdin and prints | |
+it to | |
+.I X-file | |
+with the values of the first channel | |
+(the X channel) in written to all | |
+channels, to | |
+.I Y-file | |
+with the values of the second channel | |
+(the Y channel) in written to all | |
+channels, to | |
+.I Z-file | |
+with the values of the third channel | |
+(the Z channel) in written to all | |
+channels, and to | |
+.I alpha-file | |
+with the values of the fourth channel | |
+(the alpha channel) in written to all | |
+channels. | |
+.P | |
+If | |
+.I alpha-file | |
+is omitted, values of the alpha channel | |
+are instead written to the alpha channels | |
+in | |
+.IR X-file , | |
+.IR Y-file , | |
+and | |
+.IR Z-file . | |
+.SH SEE ALSO | |
+.BR blind (7), | |
+.BR blind-arithm (1), | |
+.BR blind-cat-cols (1), | |
+.BR blind-cat-rows (1) | |
+.SH AUTHORS | |
+Mattias Andrée | |
+.RI < [email protected] > | |
diff --git a/man/blind.7 b/man/blind.7 | |
@@ -19,6 +19,9 @@ first convert it with | |
.BR blind-to-video (1). | |
.SH UTILITIES | |
.TP | |
+.BR blind-affine-colour (1) | |
+Apply an affine transformation to the colours in a video | |
+.TP | |
.BR blind-arithm (1) | |
Perform simple arithmetic on a video | |
.TP | |
@@ -247,6 +250,9 @@ Generate a video with a spiral gradient | |
.BR blind-split (1) | |
Split a video, by frame, into multiple videos | |
.TP | |
+.BR blind-split-chans (1) | |
+Split colour channels into separate videos | |
+.TP | |
.BR blind-split-cols (1) | |
Split a video vertically into multiple videos | |
.TP | |
diff --git a/src/blind-affine-colour.c b/src/blind-affine-colour.c | |
@@ -0,0 +1,118 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#ifndef TYPE | |
+#include "common.h" | |
+ | |
+USAGE("[-alp] matrix-stream") | |
+ | |
+static int skip_alpha = 0; | |
+static int linear = 0; | |
+static int per_pixel = 0; | |
+static size_t dim; | |
+ | |
+#define FILE "blind-affine-colour.c" | |
+#include "define-functions.h" | |
+ | |
+int | |
+main(int argc, char *argv[]) | |
+{ | |
+ struct stream colour, matrix; | |
+ void (*process)(struct stream *colour, struct stream *matrix); | |
+ size_t h; | |
+ | |
+ ARGBEGIN { | |
+ case 'a': | |
+ skip_alpha = 1; | |
+ break; | |
+ case 'l': | |
+ linear = 1; | |
+ break; | |
+ case 'p': | |
+ per_pixel = 1; | |
+ break; | |
+ default: | |
+ usage(); | |
+ } ARGEND; | |
+ | |
+ if (argc != 1) | |
+ usage(); | |
+ | |
+ eopen_stream(&colour, NULL); | |
+ eopen_stream(&matrix, argv[0]); | |
+ | |
+ SELECT_PROCESS_FUNCTION(&colour); | |
+ | |
+ if (strcmp(colour.pixfmt, matrix.pixfmt)) | |
+ eprintf("videos use incompatible pixel formats\n"); | |
+ | |
+ dim = colour.n_chan - (size_t)skip_alpha + (size_t)!linear; | |
+ h = matrix.height, matrix.height = dim; | |
+ echeck_dimensions(&matrix, WIDTH | HEIGHT, "matrix"); | |
+ matrix.height = h; | |
+ | |
+ if (per_pixel) { | |
+ if (matrix.height != dim * colour.height || matrix.width != di… | |
+ eprintf("the matrice should have the size %zux%zu, but… | |
+ dim * colour.height, dim * colour.width, matri… | |
+ } else { | |
+ if (matrix.height != dim || matrix.width != dim) | |
+ eprintf("the matrice should have the size %zux%zu, but… | |
+ dim, dim, matrix.height, matrix.width); | |
+ } | |
+ | |
+ fprint_stream_head(stdout, &colour); | |
+ efflush(stdout, "<stdout>"); | |
+ process(&colour, &matrix); | |
+ return 0; | |
+} | |
+ | |
+#else | |
+ | |
+static void | |
+PROCESS(struct stream *colour, struct stream *matrix) | |
+{ | |
+ char *mbuf; | |
+ TYPE *mat, *pixel, V[5], M[ELEMENTSOF(V)][ELEMENTSOF(V)]; | |
+ size_t ptr, i, j, w, x = 0, y = 0, cn; | |
+ | |
+ mbuf = emalloc2(dim, matrix->row_size); | |
+ mat = (TYPE *)mbuf; | |
+ w = matrix->width * matrix->n_chan; | |
+ cn = colour->n_chan - (size_t)skip_alpha; | |
+ | |
+ memset(M, 0, sizeof(M)); | |
+ for (i = 0; i < ELEMENTSOF(V); i++) | |
+ M[i][i] = V[i] = 1; | |
+ | |
+ do { | |
+ for (ptr = 0; ptr + colour->pixel_size <= colour->ptr; x = (x … | |
+ if (!x) { | |
+ if (!y && !eread_segment(matrix, mbuf, dim * m… | |
+ break; | |
+ if (!per_pixel) | |
+ y = (y + 1) % colour->height; | |
+ } | |
+ if (per_pixel) { | |
+ mat = (TYPE *)(mbuf + x * dim * matrix->pixel_… | |
+ for (i = 0; i < dim; i++, mat += w) | |
+ for (j = 0; j < dim; j++) | |
+ M[i][j] = mat[j * matrix->n_ch… | |
+ } | |
+ pixel = (TYPE *)(colour->buf + ptr); | |
+ for (i = 0; i < dim; i++) { | |
+ V[i] = 0; | |
+ for (j = 0; j < cn; j++) | |
+ V[i] += M[i][j] * pixel[j]; | |
+ for (; j < dim; j++) | |
+ V[i] += M[i][j]; | |
+ } | |
+ for (i = 0; i < cn; i++) | |
+ pixel[i] = V[i] / V[cn]; | |
+ } | |
+ ewriteall(STDOUT_FILENO, colour->buf, ptr, "<stdout>"); | |
+ memmove(colour->buf, colour->buf + ptr, colour->ptr -= ptr); | |
+ } while (eread_stream(colour, SIZE_MAX)); | |
+ if (colour->ptr) | |
+ eprintf("%s: incomplete frame\n", colour->file); | |
+} | |
+ | |
+#endif | |
diff --git a/src/blind-split-chans.c b/src/blind-split-chans.c | |
@@ -0,0 +1,65 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#include "common.h" | |
+ | |
+USAGE("X-file Y-file Z-file [alpha-file]") | |
+ | |
+int | |
+main(int argc, char *argv[]) | |
+{ | |
+ struct stream stream; | |
+ char xbuf[BUFSIZ], ybuf[BUFSIZ], zbuf[BUFSIZ], abuf[BUFSIZ]; | |
+ int xfd, yfd, zfd, afd = -1; | |
+ size_t i, n, ptr; | |
+ | |
+ UNOFLAGS(argc != 3 && argc != 4); | |
+ | |
+ eopen_stream(&stream, NULL); | |
+ | |
+ xfd = eopen(argv[0], O_WRONLY | O_CREAT | O_TRUNC, 0666); | |
+ yfd = eopen(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0666); | |
+ zfd = eopen(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666); | |
+ if (argc == 4) | |
+ afd = eopen(argv[3], O_WRONLY | O_CREAT | O_TRUNC, 0666); | |
+ | |
+ if (DPRINTF_HEAD(xfd, stream.frames, stream.width, stream.height, stre… | |
+ eprintf("dprintf %s:", argv[0]); | |
+ if (DPRINTF_HEAD(yfd, stream.frames, stream.width, stream.height, stre… | |
+ eprintf("dprintf %s:", argv[1]); | |
+ if (DPRINTF_HEAD(zfd, stream.frames, stream.width, stream.height, stre… | |
+ eprintf("dprintf %s:", argv[2]); | |
+ if (afd >= 0 && DPRINTF_HEAD(afd, stream.frames, stream.width, stream.… | |
+ eprintf("dprintf %s:", argv[3]); | |
+ | |
+ n = (stream.n_chan - (afd < 0)) * stream.chan_size; | |
+ do { | |
+ for (ptr = 0; ptr + stream.pixel_size <= stream.ptr; ptr += st… | |
+ for (i = 0; i < n; i += stream.chan_size) { | |
+ memcpy(xbuf + ptr + i, stream.buf + ptr + 0 * … | |
+ memcpy(ybuf + ptr + i, stream.buf + ptr + 1 * … | |
+ memcpy(zbuf + ptr + i, stream.buf + ptr + 2 * … | |
+ if (afd >= 0) | |
+ memcpy(abuf + ptr + i, stream.buf + pt… | |
+ } | |
+ if (afd < 0) { | |
+ memcpy(xbuf + ptr + n, stream.buf + ptr + 3 * … | |
+ memcpy(ybuf + ptr + n, stream.buf + ptr + 3 * … | |
+ memcpy(zbuf + ptr + n, stream.buf + ptr + 3 * … | |
+ } | |
+ } | |
+ ewriteall(xfd, xbuf, ptr, argv[0]); | |
+ ewriteall(yfd, ybuf, ptr, argv[1]); | |
+ ewriteall(zfd, zbuf, ptr, argv[2]); | |
+ if (afd >= 0) | |
+ ewriteall(afd, abuf, ptr, argv[3]); | |
+ memmove(stream.buf, stream.buf + ptr, stream.ptr -= ptr); | |
+ } while (eread_stream(&stream, SIZE_MAX)); | |
+ if (stream.ptr) | |
+ eprintf("%s: incomplete frame\n", stream.file); | |
+ | |
+ close(xfd); | |
+ close(yfd); | |
+ close(zfd); | |
+ if (afd >= 0) | |
+ close(afd); | |
+ return 0; | |
+} |