commit ff0286325a3dd1f4fe7e29e78341b9bd63e1725c
Author:     Mattias Andrée <[email protected]>
AuthorDate: Fri Jul 14 21:15:32 2017 +0200
Commit:     Mattias Andrée <[email protected]>
CommitDate: Fri Jul 14 21:15:32 2017 +0200

    blind-matrix-{rotate,shear}: add -d
    
    Signed-off-by: Mattias Andrée <[email protected]>

diff --git a/man/blind-matrix-rotate.1 b/man/blind-matrix-rotate.1
index 31ec330..3c82a3b 100644
--- 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
index 56d856d..a524cc5 100644
--- 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
index d45f2fd..0b0fc18 100644
--- 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(buf[i]);\
+                                       matrix[3][i] = -(matrix[1][i] = 
degsin(buf[i]));\
+                               }\
+                       } else 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]));\
+                               if (in_degrees) {\
+                                       matrix[4][0] = matrix[0][0] = 
degcos(buf[1]);\
+                                       matrix[3][0] = -(matrix[1][0] = 
degsin(buf[1]));\
+                               } else {\
+                                       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[1][2] = matrix[1][1] = 
matrix[1][0];\
                                matrix[3][3] = matrix[3][2] = matrix[3][1] = 
matrix[3][0];\
@@ -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
index a4c742b..0a4310e 100644
--- 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 : 
2); i++) {\
-                                       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
index 28ac4f2..47a6965 100644
--- 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__)

Reply via email to