blind-matrix-{rotate,shear}: add -d - blind - suckless command-line video editi… | |
git clone git://git.suckless.org/blind | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit ff0286325a3dd1f4fe7e29e78341b9bd63e1725c | |
parent e650c912ba86c84cdad466674a0ca0c4ebadef9c | |
Author: Mattias Andrée <[email protected]> | |
Date: Fri, 14 Jul 2017 21:15:32 +0200 | |
blind-matrix-{rotate,shear}: add -d | |
Signed-off-by: Mattias Andrée <[email protected]> | |
Diffstat: | |
M man/blind-matrix-rotate.1 | 14 +++++++++++++- | |
M man/blind-matrix-shear.1 | 5 ++++- | |
M src/blind-matrix-rotate.c | 22 ++++++++++++++++++---- | |
M src/blind-matrix-shear.c | 13 +++++++++---- | |
M src/video-math.h | 46 +++++++++++++++++++++++++++++… | |
5 files changed, 90 insertions(+), 10 deletions(-) | |
--- | |
diff --git a/man/blind-matrix-rotate.1 b/man/blind-matrix-rotate.1 | |
@@ -3,7 +3,7 @@ | |
blind-matrix-rotate - Create an affine 2D-transformation matrix for rotation | |
.SH SYNOPSIS | |
.B blind-matrix-rotate | |
-[-c] | |
+[-cd] | |
.SH DESCRIPTION | |
.B blind-matrix-rotate | |
creates an affine 2D-transformation matrix for | |
@@ -28,9 +28,21 @@ 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. | |
+.TP | |
+.B -d | |
+Input angles in degrees rather than radians. | |
.SH NOTES | |
The image is rotated anti-clockwise if the Y-axis | |
grows upwards rather than downwards. | |
+.P | |
+Due to truncation error, when rotating a multiple | |
+of 90 degrees, it is preferable to use | |
+.B -d | |
+with lets | |
+.B blind-matrix-rotate | |
+eliminate the error. If this is not done, | |
+.BR blind-invert-matrix (1) | |
+may return odd results. | |
.SH SEE ALSO | |
.BR blind (7), | |
.BR blind-from-text (1), | |
diff --git a/man/blind-matrix-shear.1 b/man/blind-matrix-shear.1 | |
@@ -3,7 +3,7 @@ | |
blind-matrix-shear - Create an affine 2D-transformation matrix for shearing | |
.SH SYNOPSIS | |
.B blind-matrix-shear | |
-[-ac] | |
+[-a [-d]] [-c] | |
.SH DESCRIPTION | |
.B blind-matrix-shear | |
creates an affine 2D-transformation matrix for | |
@@ -37,6 +37,9 @@ 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. | |
+.TP | |
+.B -d | |
+Input angles in degrees rather than radians. | |
.SH NOTES | |
The description assumes the Y-axis grows downwards. | |
.P | |
diff --git a/src/blind-matrix-rotate.c b/src/blind-matrix-rotate.c | |
@@ -1,9 +1,10 @@ | |
/* See LICENSE file for copyright and license details. */ | |
#include "common.h" | |
-USAGE("[-c]") | |
+USAGE("[-cd]") | |
static int per_channel = 0; | |
+static int in_degrees = 0; | |
#define PROCESS(TYPE)\ | |
do {\ | |
@@ -19,15 +20,25 @@ static int per_channel = 0; | |
}\ | |
\ | |
while (eread_frame(stream, buf)) {\ | |
- if (per_channel) {\ | |
+ if (per_channel && in_degrees) {\ | |
+ for (i = 0; i < 4; i++) {\ | |
+ matrix[4][i] = matrix[0][i] = degcos(b… | |
+ matrix[3][i] = -(matrix[1][i] = degsin… | |
+ }\ | |
+ } else if (per_channel) {\ | |
for (i = 0; i < 4; i++) {\ | |
matrix[4][i] = matrix[0][i] = cos(buf[… | |
matrix[3][i] = -(matrix[1][i] = sin(bu… | |
}\ | |
} else {\ | |
buf[1] *= buf[3];\ | |
- matrix[4][0] = matrix[0][0] = cos(buf[1]);\ | |
- matrix[3][0] = -(matrix[1][0] = sin(buf[1]));\ | |
+ if (in_degrees) {\ | |
+ matrix[4][0] = matrix[0][0] = degcos(b… | |
+ matrix[3][0] = -(matrix[1][0] = degsin… | |
+ } else {\ | |
+ matrix[4][0] = matrix[0][0] = cos(buf[… | |
+ matrix[3][0] = -(matrix[1][0] = sin(bu… | |
+ }\ | |
matrix[0][3] = matrix[0][2] = matrix[0][1] = m… | |
matrix[1][3] = matrix[1][2] = matrix[1][1] = m… | |
matrix[3][3] = matrix[3][2] = matrix[3][1] = m… | |
@@ -50,6 +61,9 @@ main(int argc, char *argv[]) | |
case 'c': | |
per_channel = 1; | |
break; | |
+ case 'd': | |
+ in_degrees = 1; | |
+ break; | |
default: | |
usage(); | |
} ARGEND; | |
diff --git a/src/blind-matrix-shear.c b/src/blind-matrix-shear.c | |
@@ -1,16 +1,18 @@ | |
/* See LICENSE file for copyright and license details. */ | |
#include "common.h" | |
-USAGE("[-ac]") | |
+USAGE("[-a [-d]][c]") | |
static int by_angle = 0; | |
static int per_channel = 0; | |
+static int in_degrees = 0; | |
#define PROCESS(TYPE)\ | |
do {\ | |
typedef TYPE pixel_t[4];\ | |
pixel_t matrix[9];\ | |
pixel_t buf[2];\ | |
+ TYPE conv = in_degrees ? (TYPE)(M_PI / 180.) : 1;\ | |
int i;\ | |
\ | |
for (i = 0; i < 4; i++) {\ | |
@@ -22,8 +24,8 @@ static int per_channel = 0; | |
while (eread_frame(stream, buf)) {\ | |
if (by_angle) {\ | |
for (i = !per_channel; i < (per_channel ? 4 : … | |
- buf[0][i] = tan(buf[0][i]);\ | |
- buf[1][i] = tan(buf[1][i]);\ | |
+ buf[0][i] = tan(buf[0][i] * conv);\ | |
+ buf[1][i] = tan(buf[1][i] * conv);\ | |
}\ | |
}\ | |
if (per_channel) {\ | |
@@ -55,11 +57,14 @@ main(int argc, char *argv[]) | |
case 'c': | |
per_channel = 1; | |
break; | |
+ case 'd': | |
+ in_degrees = 1; | |
+ break; | |
default: | |
usage(); | |
} ARGEND; | |
- if (argc) | |
+ if (argc || (in_degrees && !by_angle)) | |
usage(); | |
eopen_stream(&stream, NULL); | |
diff --git a/src/video-math.h b/src/video-math.h | |
@@ -31,6 +31,50 @@ posmodf(float a, float b) | |
return x < 0 ? x + b : x; | |
} | |
+static inline double | |
+degsin(double u) | |
+{ | |
+ if (!fmod(u, 90)) { | |
+ int64_t v = u; | |
+ v = ((v / 90) % 4 + 4) % 4; | |
+ return ((double[]){0, 1, 0, -1})[v]; | |
+ } | |
+ return sin(u * (M_PI / 180.0)); | |
+} | |
+ | |
+static inline float | |
+degsinf(float u) | |
+{ | |
+ if (!fmodf(u, 90)) { | |
+ int64_t v = u; | |
+ v = ((v / 90) % 4 + 4) % 4; | |
+ return ((float[]){0, 1, 0, -1})[v]; | |
+ } | |
+ return sin(u * (float)(M_PI / 180.0)); | |
+} | |
+ | |
+static inline double | |
+degcos(double u) | |
+{ | |
+ if (!fmod(u, 90)) { | |
+ int64_t v = u; | |
+ v = ((v / 90) % 4 + 4) % 4; | |
+ return ((double[]){1, 0, -1, 0})[v]; | |
+ } | |
+ return cos(u * (M_PI / 180.0)); | |
+} | |
+ | |
+static inline float | |
+degcosf(float u) | |
+{ | |
+ if (!fmodf(u, 90)) { | |
+ int64_t v = u; | |
+ v = ((v / 90) % 4 + 4) % 4; | |
+ return ((float[]){1, 0, -1, 0})[v]; | |
+ } | |
+ return cos(u * (float)(M_PI / 180.0)); | |
+} | |
+ | |
#define GENERIC(TYPE, FUNC, ...)\ | |
TYPE: FUNC(__VA_ARGS__),\ | |
TYPE *: FUNC(__VA_ARGS__),\ | |
@@ -73,6 +117,8 @@ posmodf(float a, float b) | |
#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 degcos(...) MATH_GENERIC_1(degcos, __VA_ARGS__) | |
+#define degsin(...) MATH_GENERIC_1(degsin, __VA_ARGS__) | |
#define srgb_encode(...) BLIND_GENERIC_1(srgb_encode, __VA_ARGS__) | |
#define srgb_decode(...) BLIND_GENERIC_1(srgb_decode, __VA_ARGS__) |