blind

suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log | Files | Refs | README | LICENSE

commit 0ca8f64f61b534ba2428236fec2c8879fe58c059
parent b384c0cc8c69783495e1f21f3fd0f3e6253645b1
Author: Mattias Andrée <maandree@kth.se>
Date:   Fri, 14 Jul 2017 16:30:30 +0200

Add blind-matrix-{orthoproject,reflect,rotate,scale,shear,translate,transpose}

Signed-off-by: Mattias Andrée <maandree@kth.se>

Diffstat:
Makefile | 7+++++++
README | 21+++++++++++++++++++++
man/blind-matrix-orthoproject.1 | 43+++++++++++++++++++++++++++++++++++++++++++
man/blind-matrix-reflect.1 | 43+++++++++++++++++++++++++++++++++++++++++++
man/blind-matrix-rotate.1 | 45+++++++++++++++++++++++++++++++++++++++++++++
man/blind-matrix-scale.1 | 43+++++++++++++++++++++++++++++++++++++++++++
man/blind-matrix-shear.1 | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
man/blind-matrix-translate.1 | 47+++++++++++++++++++++++++++++++++++++++++++++++
man/blind-matrix-transpose.1 | 43+++++++++++++++++++++++++++++++++++++++++++
man/blind.7 | 21+++++++++++++++++++++
src/blind-matrix-orthoproject.c | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/blind-matrix-reflect.c | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/blind-matrix-rotate.c | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/blind-matrix-scale.c | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/blind-matrix-shear.c | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/blind-matrix-translate.c | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/blind-matrix-transpose.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/video-math.h | 1+
18 files changed, 935 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -41,6 +41,13 @@ BIN =\ blind-invert-luma\ blind-linear-gradient\ blind-make-kernel\ + blind-matrix-orthoproject\ + blind-matrix-reflect\ + blind-matrix-rotate\ + blind-matrix-scale\ + blind-matrix-shear\ + blind-matrix-translate\ + blind-matrix-transpose\ blind-mosaic\ blind-mosaic-edges\ blind-next-frame\ diff --git a/README b/README @@ -117,6 +117,27 @@ UTILITIES blind-make-kernel(1) Create a custom convolution matrix + blind-matrix-orthoproject(1) + Create an affine 2D-transformation matrix for othogonal projection + + blind-matrix-reflect(1) + Create an affine 2D-transformation matrix for reflection about a line + + blind-matrix-rotate(1) + Create an affine 2D-transformation matrix for rotation + + blind-matrix-scale(1) + Create an affine 2D-transformation matrix for scaling + + blind-matrix-shear(1) + Create an affine 2D-transformation matrix for shearing + + blind-matrix-translate(1) + Create an affine 2D-transformation matrix for translation + + blind-matrix-transpose(1) + Create an affine 2D-transformation matrix for transposition + blind-mosaic(1) Redraw each frame in video as a mosaic diff --git a/man/blind-matrix-orthoproject.1 b/man/blind-matrix-orthoproject.1 @@ -0,0 +1,43 @@ +.TH BLIND-MATRIX-ORTHOPROJECT 1 blind +.SH NAME +blind-matrix-orthoproject - Create an affine 2D-transformation matrix for othogonal projection +.SH SYNOPSIS +.B blind-matrix-orthoproject +[-c] +.SH DESCRIPTION +.B blind-matrix-orthoproject +creates an affine 2D-transformation matrix for +othogonal projection. The parameters for the +matrix is read in stdin in format of a blind video, +one matrix per frame in stdin created and printed +to stdout in format of a blind video. +.P +Each frame in stdin shall contain exactly 2 pixels, +the first pixel holds the x-value of the vector the +image is projected along, the second pixel holds the +y-value of this vector. +.P +The luma (encoding in the Y-channel, the second +channel) multiplied by the alpha (the fourth channel) +of the input pixels are used as the values. Each +values in the resulting matrices are stored +in all channels. +.SH OPTIONS +.TP +.B -c +Create different matrices for each channel. Use +values from each channel in stdin to create +matrices whose values are stored in the same +channels in stdout. +.SH SEE ALSO +.BR blind (7), +.BR blind-from-text (1), +.BR blind-matrix-reflect (1), +.BR blind-matrix-rotate (1), +.BR blind-matrix-scale (1), +.BR blind-matrix-shear (1), +.BR blind-matrix-translate (1), +.BR blind-matrix-transpose (1) +.SH AUTHORS +Mattias Andrée +.RI < maandree@kth.se > diff --git a/man/blind-matrix-reflect.1 b/man/blind-matrix-reflect.1 @@ -0,0 +1,43 @@ +.TH BLIND-MATRIX-REFLECT 1 blind +.SH NAME +blind-matrix-reflect - Create an affine 2D-transformation matrix for reflection about a line +.SH SYNOPSIS +.B blind-matrix-reflect +[-c] +.SH DESCRIPTION +.B blind-matrix-reflect +creates an affine 2D-transformation matrix for +reflection about a line. The parameters for the +matrix is read in stdin in format of a blind video, +one matrix per frame in stdin created and printed +to stdout in format of a blind video. +.P +Each frame in stdin shall contain exactly 2 pixels, +the first pixel holds the x-value of the line going +out from origo the image is reflected around, the +second pixel holds the y-value of this line. +.P +The luma (encoding in the Y-channel, the second +channel) multiplied by the alpha (the fourth channel) +of the input pixels are used as the values. Each +values in the resulting matrices are stored +in all channels. +.SH OPTIONS +.TP +.B -c +Create different matrices for each channel. Use +values from each channel in stdin to create +matrices whose values are stored in the same +channels in stdout. +.SH SEE ALSO +.BR blind (7), +.BR blind-from-text (1), +.BR blind-matrix-orthoproject (1), +.BR blind-matrix-rotate (1), +.BR blind-matrix-scale (1), +.BR blind-matrix-shear (1), +.BR blind-matrix-translate (1), +.BR blind-matrix-transpose (1) +.SH AUTHORS +Mattias Andrée +.RI < maandree@kth.se > diff --git a/man/blind-matrix-rotate.1 b/man/blind-matrix-rotate.1 @@ -0,0 +1,45 @@ +.TH BLIND-MATRIX-ROTATE 1 blind +.SH NAME +blind-matrix-rotate - Create an affine 2D-transformation matrix for rotation +.SH SYNOPSIS +.B blind-matrix-rotate +[-c] +.SH DESCRIPTION +.B blind-matrix-rotate +creates an affine 2D-transformation matrix for +rotation. The parameters for the matrix is read +in stdin in format of a blind video, one matrix +per frame in stdin created and printed to stdout +in format of a blind video. +.P +Each frame in stdin shall contain exactly 1 pixel, +this pixel holds the number of radians the image +is to be rotated clockwise around origo. +.P +The luma (encoding in the Y-channel, the second +channel) multiplied by the alpha (the fourth channel) +of the input pixels are used as the values. Each +values in the resulting matrices are stored +in all channels. +.SH OPTIONS +.TP +.B -c +Create different matrices for each channel. Use +values from each channel in stdin to create +matrices whose values are stored in the same +channels in stdout. +.SH NOTES +The image is rotated anti-clockwise if the Y-axis +grows upwards rather than downwards. +.SH SEE ALSO +.BR blind (7), +.BR blind-from-text (1), +.BR blind-matrix-orthoproject (1), +.BR blind-matrix-reflect (1), +.BR blind-matrix-scale (1), +.BR blind-matrix-shear (1), +.BR blind-matrix-translate (1), +.BR blind-matrix-transpose (1) +.SH AUTHORS +Mattias Andrée +.RI < maandree@kth.se > diff --git a/man/blind-matrix-scale.1 b/man/blind-matrix-scale.1 @@ -0,0 +1,43 @@ +.TH BLIND-MATRIX-SCALE 1 blind +.SH NAME +blind-matrix-scale - Create an affine 2D-transformation matrix for scaling +.SH SYNOPSIS +.B blind-matrix-scale +[-c] +.SH DESCRIPTION +.B blind-matrix-scale +creates an affine 2D-transformation matrix for +scaling. The parameters for the matrix is read +in stdin in format of a blind video, one matrix +per frame in stdin created and printed to stdout +in format of a blind video. +.P +Each frame in stdin shall contain exactly 2 pixel, +the first pixel holds the scale factor for the +width and the second pixel holds the scale factor +for the height. +.P +The luma (encoding in the Y-channel, the second +channel) multiplied by the alpha (the fourth channel) +of the input pixels are used as the values. Each +values in the resulting matrices are stored +in all channels. +.SH OPTIONS +.TP +.B -c +Create different matrices for each channel. Use +values from each channel in stdin to create +matrices whose values are stored in the same +channels in stdout. +.SH SEE ALSO +.BR blind (7), +.BR blind-from-text (1), +.BR blind-matrix-orthoproject (1), +.BR blind-matrix-reflect (1), +.BR blind-matrix-rotate (1), +.BR blind-matrix-shear (1), +.BR blind-matrix-translate (1), +.BR blind-matrix-transpose (1) +.SH AUTHORS +Mattias Andrée +.RI < maandree@kth.se > diff --git a/man/blind-matrix-shear.1 b/man/blind-matrix-shear.1 @@ -0,0 +1,58 @@ +.TH BLIND-MATRIX-SHEAR 1 blind +.SH NAME +blind-matrix-shear - Create an affine 2D-transformation matrix for shearing +.SH SYNOPSIS +.B blind-matrix-shear +[-ac] +.SH DESCRIPTION +.B blind-matrix-shear +creates an affine 2D-transformation matrix for +shearing. The parameters for the matrix is read +in stdin in format of a blind video, one matrix +per frame in stdin created and printed to stdout +in format of a blind video. +.P +Each frame in stdin shall contain exactly 2 pixel. +The first pixel holds the amount the image shall +be sheared horizontally, that is, how much all +pixels 1 pixel above the X-axis shall be moved +rightward. The second pixel holds the amount the +image shall be sheared vertically, that is, how +much all pixels 1 pixel right of the Y-axis shall +be moved downward. +.P +The luma (encoding in the Y-channel, the second +channel) multiplied by the alpha (the fourth channel) +of the input pixels are used as the values. Each +values in the resulting matrices are stored +in all channels. +.SH OPTIONS +.TP +.B -a +The pixels holds the angles of the shearing rather +than the amount of the shearing. +.TP +.B -c +Create different matrices for each channel. Use +values from each channel in stdin to create +matrices whose values are stored in the same +channels in stdout. +.SH NOTES +The description assumes the Y-axis grows downwards. +.P +Horizontal shearing and vertical shearing is not +mutually commutative, this tool performs the +shearing at the same time rather than after each +other. +.SH SEE ALSO +.BR blind (7), +.BR blind-from-text (1), +.BR blind-matrix-orthoproject (1), +.BR blind-matrix-reflect (1), +.BR blind-matrix-rotate (1), +.BR blind-matrix-scale (1), +.BR blind-matrix-translate (1), +.BR blind-matrix-transpose (1) +.SH AUTHORS +Mattias Andrée +.RI < maandree@kth.se > diff --git a/man/blind-matrix-translate.1 b/man/blind-matrix-translate.1 @@ -0,0 +1,47 @@ +.TH BLIND-MATRIX-TRANSLATE 1 blind +.SH NAME +blind-matrix-translate - Create an affine 2D-transformation matrix for translation +.SH SYNOPSIS +.B blind-matrix-translate +[-c] +.SH DESCRIPTION +.B blind-matrix-translate +creates an affine 2D-transformation matrix for +translation. The parameters for the matrix is read +in stdin in format of a blind video, one matrix +per frame in stdin created and printed to stdout +in format of a blind video. +.P +Each frame in stdin shall contain exactly 2 pixel, +the first pixel holds the number of pixels the +image shall be translated rightwards, and the +second pixel holds the number of pixels the +image shall be translated downwards. +.P +The luma (encoding in the Y-channel, the second +channel) multiplied by the alpha (the fourth channel) +of the input pixels are used as the values. Each +values in the resulting matrices are stored +in all channels. +.SH OPTIONS +.TP +.B -c +Create different matrices for each channel. Use +values from each channel in stdin to create +matrices whose values are stored in the same +channels in stdout. +.SH NOTES +The image upwards rather than downwards if the +Y-axis grows upwards rather than downwards. +.SH SEE ALSO +.BR blind (7), +.BR blind-from-text (1), +.BR blind-matrix-orthoproject (1), +.BR blind-matrix-reflect (1), +.BR blind-matrix-rotate (1), +.BR blind-matrix-scale (1), +.BR blind-matrix-shear (1), +.BR blind-matrix-transpose (1) +.SH AUTHORS +Mattias Andrée +.RI < maandree@kth.se > diff --git a/man/blind-matrix-transpose.1 b/man/blind-matrix-transpose.1 @@ -0,0 +1,43 @@ +.TH BLIND-MATRIX-TRANSPOSE 1 blind +.SH NAME +blind-matrix-transpose - Create an affine 2D-transformation matrix for transposition +.SH SYNOPSIS +.B blind-matrix-transpose +[-c] +.SH DESCRIPTION +.B blind-matrix-transpose +creates an affine 2D-transformation matrix for +transposition. The parameters for the matrix is read +in stdin in format of a blind video, one matrix +per frame in stdin created and printed to stdout +in format of a blind video. +.P +Each frame in stdin shall contain exactly 1 pixel, +this pixel holds degree of the transposition, 0 +meaning no transposition at all, 1 meaning full +transposition. +.P +The luma (encoding in the Y-channel, the second +channel) multiplied by the alpha (the fourth channel) +of the input pixels are used as the values. Each +values in the resulting matrices are stored +in all channels. +.SH OPTIONS +.TP +.B -c +Create different matrices for each channel. Use +values from each channel in stdin to create +matrices whose values are stored in the same +channels in stdout. +.SH SEE ALSO +.BR blind (7), +.BR blind-from-text (1), +.BR blind-matrix-orthoproject (1), +.BR blind-matrix-reflect (1), +.BR blind-matrix-rotate (1), +.BR blind-matrix-scale (1), +.BR blind-matrix-shear (1), +.BR blind-matrix-translate (1) +.SH AUTHORS +Mattias Andrée +.RI < maandree@kth.se > diff --git a/man/blind.7 b/man/blind.7 @@ -133,6 +133,27 @@ Generate a video with a linear gradient .BR blind-make-kernel (1) Create a custom convolution matrix .TP +.BR blind-matrix-orthoproject (1) +Create an affine 2D-transformation matrix for othogonal projection +.TP +.BR blind-matrix-reflect (1) +Create an affine 2D-transformation matrix for reflection about a line +.TP +.BR blind-matrix-rotate (1) +Create an affine 2D-transformation matrix for rotation +.TP +.BR blind-matrix-scale (1) +Create an affine 2D-transformation matrix for scaling +.TP +.BR blind-matrix-shear (1) +Create an affine 2D-transformation matrix for shearing +.TP +.BR blind-matrix-translate (1) +Create an affine 2D-transformation matrix for translation +.TP +.BR blind-matrix-transpose (1) +Create an affine 2D-transformation matrix for transposition +.TP .BR blind-mosaic (1) Redraw each frame in video as a mosaic .TP diff --git a/src/blind-matrix-orthoproject.c b/src/blind-matrix-orthoproject.c @@ -0,0 +1,89 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-c]") + +static int per_channel = 0; + +#define PROCESS(TYPE)\ + do {\ + typedef TYPE pixel_t[4];\ + pixel_t matrix[9];\ + pixel_t buf[2];\ + TYPE x2, y2, norm2;\ + int i;\ + \ + for (i = 0; i < 4; i++) {\ + matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\ + matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\ + matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\ + }\ + \ + while (eread_frame(stream, buf)) {\ + if (per_channel) {\ + for (i = 0; i < 4; i++) {\ + x2 = buf[0][i] * buf[0][i];\ + y2 = buf[1][i] * buf[1][i];\ + norm2 = x2 + y2;\ + matrix[0][i] = x2 / norm2;\ + matrix[4][i] = y2 / norm2;\ + matrix[3][i] = matrix[1][i] = buf[0][i] * buf[1][i] / norm2;\ + }\ + } else {\ + buf[0][1] *= buf[0][3];\ + buf[1][1] *= buf[1][3];\ + x2 = buf[0][1] * buf[0][1];\ + y2 = buf[1][1] * buf[1][1];\ + norm2 = x2 + y2;\ + matrix[0][0] = x2 / norm2;\ + matrix[4][0] = y2 / norm2;\ + matrix[3][0] = matrix[1][0] = buf[0][1] * buf[1][1] / norm2;\ + matrix[0][3] = matrix[0][2] = matrix[0][1] = matrix[0][0];\ + matrix[1][3] = matrix[1][2] = matrix[1][1] = matrix[1][0];\ + matrix[3][3] = matrix[3][2] = matrix[3][1] = matrix[3][0];\ + matrix[4][3] = matrix[4][2] = matrix[4][1] = matrix[4][0];\ + }\ + ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");\ + }\ + } while (0) + +static void process_lf(struct stream *stream) { PROCESS(double); } +static void process_f(struct stream *stream) { PROCESS(float); } + +int +main(int argc, char *argv[]) +{ + struct stream stream; + void (*process)(struct stream *stream); + + ARGBEGIN { + case 'c': + per_channel = 1; + break; + default: + usage(); + } ARGEND; + + if (argc) + usage(); + + eopen_stream(&stream, NULL); + + if (stream.width > 2 || stream.height > 2 || stream.width * stream.height != 2) + eprintf("<stdin>: each frame must contain exactly 2 pixels\n"); + + stream.width = 3; + stream.height = 3; + fprint_stream_head(stdout, &stream); + efflush(stdout, "<stdout>"); + + if (!strcmp(stream.pixfmt, "xyza")) + process = process_lf; + else if (!strcmp(stream.pixfmt, "xyza f")) + process = process_f; + else + eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt); + + process(&stream); + return 0; +} diff --git a/src/blind-matrix-reflect.c b/src/blind-matrix-reflect.c @@ -0,0 +1,87 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-c]") + +static int per_channel = 0; + +#define PROCESS(TYPE)\ + do {\ + typedef TYPE pixel_t[4];\ + pixel_t matrix[9];\ + pixel_t buf[2];\ + TYPE x2, y2, norm2;\ + int i;\ + \ + for (i = 0; i < 4; i++) {\ + matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\ + matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\ + matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\ + }\ + \ + while (eread_frame(stream, buf)) {\ + if (per_channel) {\ + for (i = 0; i < 4; i++) {\ + x2 = buf[0][i] * buf[0][i];\ + y2 = buf[1][i] * buf[1][i];\ + norm2 = x2 + y2;\ + matrix[4][i] = -(matrix[0][i] = (x2 - y2) / norm2);\ + matrix[3][i] = matrix[1][i] = 2 * buf[0][i] * buf[1][i] / norm2;\ + }\ + } else {\ + buf[0][1] *= buf[0][3];\ + buf[1][1] *= buf[1][3];\ + x2 = buf[0][1] * buf[0][1];\ + y2 = buf[1][1] * buf[1][1];\ + norm2 = x2 + y2;\ + matrix[4][0] = -(matrix[0][0] = (x2 - y2) / norm2);\ + matrix[3][0] = matrix[1][0] = 2 * buf[0][1] * buf[1][1] / norm2;\ + matrix[0][3] = matrix[0][2] = matrix[0][1] = matrix[0][0];\ + matrix[1][3] = matrix[1][2] = matrix[1][1] = matrix[1][0];\ + matrix[3][3] = matrix[3][2] = matrix[3][1] = matrix[3][0];\ + matrix[4][3] = matrix[4][2] = matrix[4][1] = matrix[4][0];\ + }\ + ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");\ + }\ + } while (0) + +static void process_lf(struct stream *stream) { PROCESS(double); } +static void process_f(struct stream *stream) { PROCESS(float); } + +int +main(int argc, char *argv[]) +{ + struct stream stream; + void (*process)(struct stream *stream); + + ARGBEGIN { + case 'c': + per_channel = 1; + break; + default: + usage(); + } ARGEND; + + if (argc) + usage(); + + eopen_stream(&stream, NULL); + + if (stream.width > 2 || stream.height > 2 || stream.width * stream.height != 2) + eprintf("<stdin>: each frame must contain exactly 2 pixels\n"); + + stream.width = 3; + stream.height = 3; + fprint_stream_head(stdout, &stream); + efflush(stdout, "<stdout>"); + + if (!strcmp(stream.pixfmt, "xyza")) + process = process_lf; + else if (!strcmp(stream.pixfmt, "xyza f")) + process = process_f; + else + eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt); + + process(&stream); + return 0; +} diff --git a/src/blind-matrix-rotate.c b/src/blind-matrix-rotate.c @@ -0,0 +1,79 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-c]") + +static int per_channel = 0; + +#define PROCESS(TYPE)\ + do {\ + typedef TYPE pixel_t[4];\ + pixel_t matrix[9];\ + pixel_t buf;\ + int i;\ + \ + for (i = 0; i < 4; i++) {\ + matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\ + matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\ + matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\ + }\ + \ + while (eread_frame(stream, buf)) {\ + if (per_channel) {\ + for (i = 0; i < 4; i++) {\ + matrix[4][i] = matrix[0][i] = cos(buf[i]);\ + matrix[3][i] = -(matrix[1][i] = sin(buf[i]));\ + }\ + } else {\ + buf[1] *= buf[3];\ + matrix[4][0] = matrix[0][0] = cos(buf[1]);\ + matrix[3][0] = -(matrix[1][0] = sin(buf[1]));\ + matrix[0][3] = matrix[0][2] = matrix[0][1] = matrix[0][0];\ + matrix[1][3] = matrix[0][2] = matrix[0][1] = matrix[1][0];\ + matrix[3][3] = matrix[0][2] = matrix[0][1] = matrix[3][0];\ + matrix[4][3] = matrix[0][2] = matrix[0][1] = matrix[4][0];\ + }\ + ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");\ + }\ + } while (0) + +static void process_lf(struct stream *stream) { PROCESS(double); } +static void process_f(struct stream *stream) { PROCESS(float); } + +int +main(int argc, char *argv[]) +{ + struct stream stream; + void (*process)(struct stream *stream); + + ARGBEGIN { + case 'c': + per_channel = 1; + break; + default: + usage(); + } ARGEND; + + if (argc) + usage(); + + eopen_stream(&stream, NULL); + + if (stream.width != 1 && stream.height != 1) + eprintf("<stdin>: each frame must contain exactly 1 pixels\n"); + + stream.width = 3; + stream.height = 3; + fprint_stream_head(stdout, &stream); + efflush(stdout, "<stdout>"); + + if (!strcmp(stream.pixfmt, "xyza")) + process = process_lf; + else if (!strcmp(stream.pixfmt, "xyza f")) + process = process_f; + else + eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt); + + process(&stream); + return 0; +} diff --git a/src/blind-matrix-scale.c b/src/blind-matrix-scale.c @@ -0,0 +1,74 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-c]") + +static int per_channel = 0; + +#define PROCESS(TYPE)\ + do {\ + typedef TYPE pixel_t[4];\ + pixel_t matrix[9];\ + pixel_t buf[2];\ + int i;\ + \ + for (i = 0; i < 4; i++) {\ + matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\ + matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\ + matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\ + }\ + \ + while (eread_frame(stream, buf)) {\ + if (per_channel) {\ + for (i = 0; i < 4; i++) {\ + matrix[0][i] = buf[0][i];\ + matrix[4][i] = buf[1][i];\ + }\ + } else {\ + matrix[0][3] = matrix[0][2] = matrix[0][1] = matrix[0][0] = buf[0][1] * buf[0][3];\ + matrix[4][3] = matrix[4][2] = matrix[4][1] = matrix[4][0] = buf[1][1] * buf[1][3];\ + }\ + ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");\ + }\ + } while (0) + +static void process_lf(struct stream *stream) { PROCESS(double); } +static void process_f(struct stream *stream) { PROCESS(float); } + +int +main(int argc, char *argv[]) +{ + struct stream stream; + void (*process)(struct stream *stream); + + ARGBEGIN { + case 'c': + per_channel = 1; + break; + default: + usage(); + } ARGEND; + + if (argc) + usage(); + + eopen_stream(&stream, NULL); + + if (stream.width > 2 || stream.height > 2 || stream.width * stream.height != 2) + eprintf("<stdin>: each frame must contain exactly 2 pixels\n"); + + stream.width = 3; + stream.height = 3; + fprint_stream_head(stdout, &stream); + efflush(stdout, "<stdout>"); + + if (!strcmp(stream.pixfmt, "xyza")) + process = process_lf; + else if (!strcmp(stream.pixfmt, "xyza f")) + process = process_f; + else + eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt); + + process(&stream); + return 0; +} diff --git a/src/blind-matrix-shear.c b/src/blind-matrix-shear.c @@ -0,0 +1,84 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-ac]") + +static int by_angle = 0; +static int per_channel = 0; + +#define PROCESS(TYPE)\ + do {\ + typedef TYPE pixel_t[4];\ + pixel_t matrix[9];\ + pixel_t buf[2];\ + int i;\ + \ + for (i = 0; i < 4; i++) {\ + matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\ + matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\ + matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\ + }\ + \ + while (eread_frame(stream, buf)) {\ + if (by_angle) {\ + for (i = !per_channel; i < (per_channel ? 4 : 2); i++) {\ + buf[0][i] = tan(buf[0][i]);\ + buf[1][i] = tan(buf[1][i]);\ + }\ + }\ + if (per_channel) {\ + for (i = 0; i < 4; i++) {\ + matrix[1][i] = buf[0][i];\ + matrix[3][i] = buf[1][i];\ + }\ + } else {\ + matrix[1][3] = matrix[1][2] = matrix[1][1] = matrix[1][0] = buf[0][1] * buf[0][3];\ + matrix[3][3] = matrix[3][2] = matrix[3][1] = matrix[3][0] = buf[1][1] * buf[1][3];\ + }\ + ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");\ + }\ + } while (0) + +static void process_lf(struct stream *stream) { PROCESS(double); } +static void process_f(struct stream *stream) { PROCESS(float); } + +int +main(int argc, char *argv[]) +{ + struct stream stream; + void (*process)(struct stream *stream); + + ARGBEGIN { + case 'a': + by_angle = 1; + break; + case 'c': + per_channel = 1; + break; + default: + usage(); + } ARGEND; + + if (argc) + usage(); + + eopen_stream(&stream, NULL); + + if (stream.width > 2 || stream.height > 2 || stream.width * stream.height != 2) + eprintf("<stdin>: each frame must contain exactly 2 pixels\n"); + + stream.width = 3; + stream.height = 3; + fprint_stream_head(stdout, &stream); + efflush(stdout, "<stdout>"); + + if (!strcmp(stream.pixfmt, "xyza")) + process = process_lf; + else if (!strcmp(stream.pixfmt, "xyza f")) + process = process_f; + else + eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt); + + process(&stream); + return 0; +} diff --git a/src/blind-matrix-translate.c b/src/blind-matrix-translate.c @@ -0,0 +1,74 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-c]") + +static int per_channel = 0; + +#define PROCESS(TYPE)\ + do {\ + typedef TYPE pixel_t[4];\ + pixel_t matrix[9];\ + pixel_t buf[2];\ + int i;\ + \ + for (i = 0; i < 4; i++) {\ + matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\ + matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\ + matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\ + }\ + \ + while (eread_frame(stream, buf)) {\ + if (per_channel) {\ + for (i = 0; i < 4; i++) {\ + matrix[2][i] = buf[0][i];\ + matrix[5][i] = buf[1][i];\ + }\ + } else {\ + matrix[2][3] = matrix[2][2] = matrix[2][1] = matrix[2][0] = buf[0][1] * buf[0][3];\ + matrix[5][3] = matrix[5][2] = matrix[5][1] = matrix[5][0] = buf[1][1] * buf[1][3];\ + }\ + ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");\ + }\ + } while (0) + +static void process_lf(struct stream *stream) { PROCESS(double); } +static void process_f(struct stream *stream) { PROCESS(float); } + +int +main(int argc, char *argv[]) +{ + struct stream stream; + void (*process)(struct stream *stream); + + ARGBEGIN { + case 'c': + per_channel = 1; + break; + default: + usage(); + } ARGEND; + + if (argc) + usage(); + + eopen_stream(&stream, NULL); + + if (stream.width > 2 || stream.height > 2 || stream.width * stream.height != 2) + eprintf("<stdin>: each frame must contain exactly 2 pixels\n"); + + stream.width = 3; + stream.height = 3; + fprint_stream_head(stdout, &stream); + efflush(stdout, "<stdout>"); + + if (!strcmp(stream.pixfmt, "xyza")) + process = process_lf; + else if (!strcmp(stream.pixfmt, "xyza f")) + process = process_f; + else + eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt); + + process(&stream); + return 0; +} diff --git a/src/blind-matrix-transpose.c b/src/blind-matrix-transpose.c @@ -0,0 +1,76 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-c]") + +static int per_channel = 0; + +#define PROCESS(TYPE)\ + do {\ + typedef TYPE pixel_t[4];\ + pixel_t matrix[9];\ + pixel_t buf;\ + int i;\ + \ + for (i = 0; i < 4; i++) {\ + matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\ + matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\ + matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\ + }\ + \ + while (eread_frame(stream, buf)) {\ + if (per_channel) {\ + for (i = 0; i < 4; i++) {\ + matrix[3][i] = matrix[1][i] = buf[i];\ + matrix[4][i] = matrix[0][i] = 1 - buf[i];\ + }\ + } else {\ + for (i = 0; i < 4; i++) {\ + matrix[3][i] = matrix[1][i] = buf[1] * buf[3];\ + matrix[4][i] = matrix[0][i] = 1 - matrix[3][i];\ + }\ + }\ + ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");\ + }\ + } while (0) + +static void process_lf(struct stream *stream) { PROCESS(double); } +static void process_f(struct stream *stream) { PROCESS(float); } + +int +main(int argc, char *argv[]) +{ + struct stream stream; + void (*process)(struct stream *stream); + + ARGBEGIN { + case 'c': + per_channel = 1; + break; + default: + usage(); + } ARGEND; + + if (argc) + usage(); + + eopen_stream(&stream, NULL); + + if (stream.width != 1 && stream.height != 12) + eprintf("<stdin>: each frame must contain exactly 1 pixels\n"); + + stream.width = 3; + stream.height = 3; + fprint_stream_head(stdout, &stream); + efflush(stdout, "<stdout>"); + + if (!strcmp(stream.pixfmt, "xyza")) + process = process_lf; + else if (!strcmp(stream.pixfmt, "xyza f")) + process = process_f; + else + eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt); + + process(&stream); + return 0; +} diff --git a/src/video-math.h b/src/video-math.h @@ -71,6 +71,7 @@ posmodf(float a, float b) #define posmod(...) MATH_GENERIC_N(posmod, __VA_ARGS__) #define cos(...) MATH_GENERIC_1(cos, __VA_ARGS__) #define sin(...) MATH_GENERIC_1(sin, __VA_ARGS__) +#define tan(...) MATH_GENERIC_1(tan, __VA_ARGS__) #define atan2(...) MATH_GENERIC_N(atan2, __VA_ARGS__) #define srgb_encode(...) BLIND_GENERIC_1(srgb_encode, __VA_ARGS__)