blind-kernel: add more kernels - blind - suckless command-line video editing ut… | |
git clone git://git.suckless.org/blind | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit a79568e8ab6bd516bef02e87855c23526356f20a | |
parent ffeba5cae6ebf01f421e11eee2c4d050da0bb3f3 | |
Author: Mattias Andrée <[email protected]> | |
Date: Wed, 26 Jul 2017 17:50:58 +0200 | |
blind-kernel: add more kernels | |
Signed-off-by: Mattias Andrée <[email protected]> | |
Diffstat: | |
M man/blind-kernel.1 | 128 +++++++++++++++++++++++++----… | |
M src/blind-kernel.c | 98 +++++++++++++++++++++++++++++… | |
2 files changed, 198 insertions(+), 28 deletions(-) | |
--- | |
diff --git a/man/blind-kernel.1 b/man/blind-kernel.1 | |
@@ -20,6 +20,85 @@ argument and is tuned with | |
.IR parameter s. | |
.SH KERNELS | |
.TP | |
+.RI ' \fBbox\ blur\fP '\ [-w\ weight ]\ [ spread \ |\ x-spread \ y-spread ] | |
+Creates a box blur kernel. Unless | |
+.B -w | |
+is used, the kernel is unweighted, otherwise it has the specified | |
+.IR weight . | |
+The kernel will have the spread 1, the specified | |
+.IR spread , | |
+or | |
+.I x-spread | |
+as the horizontal spread and | |
+.I y-spread | |
+as the vertical spread. | |
+.TP | |
+.BR emboss \ [\fIdirection\fP] | |
+Create an emboss kernel with the specified | |
+.IR direction . | |
+The | |
+.I direction | |
+must be | |
+.BR N ; | |
+.BR NW | |
+or | |
+.BR WN ; | |
+.BR W ; | |
+.BR SW | |
+or | |
+.BR WS ; | |
+.BR S ; | |
+.BR SE | |
+or | |
+.BR ES ; | |
+.BR E ; | |
+.BR NE | |
+or | |
+.BR EN . | |
+If no | |
+.I direction | |
+is specified, | |
+.B SE | |
+is used. | |
+.TP | |
+.RI \fBgaussian\fP\ [-s\ spread ]\ [-u]\ standard-deviation | |
+Creates a Gaussian blur kernel with the standard deviation | |
+.IR standard-deviation . | |
+If | |
+.B -u | |
+is used, the a Gaussian unsharpen kernel is created. If | |
+.B -s | |
+is specified, the specified | |
+.I spread | |
+will be used, otherwise the spread will be selected automatically. | |
+.TP | |
+.BI gradient\ direction | |
+Create a gradient detection kernel with the specified | |
+.IR direction . | |
+The | |
+.I direction | |
+must be | |
+.BR N ; | |
+.BR NW | |
+or | |
+.BR WN ; | |
+.BR W ; | |
+.BR SW | |
+or | |
+.BR WS ; | |
+.BR S | |
+or | |
+.BR H ; | |
+.BR SE | |
+or | |
+.BR ES ; | |
+.BR E | |
+or | |
+.BR V ; | |
+.BR NE | |
+or | |
+.BR EN . | |
+.TP | |
.BI kirsch\ direction | |
Create a Kirsch kernel with the specified | |
.IR direction . | |
@@ -56,34 +135,37 @@ or | |
or | |
.BR EN . | |
.TP | |
-.RI ' \fBbox\ blur\fP '\ [-w\ weight ]\ [ spread \ |\ x-spread \ y-spread ] | |
-Creates a box blur kernel. Unless | |
-.B -w | |
-is used, the kernel is unweighted, otherwise it has the specified | |
-.IR weight . | |
-The kernel will have the spread 1, the specified | |
-.IR spread , | |
-or | |
-.I x-spread | |
-as the horizontal spread and | |
-.I y-spread | |
-as the vertical spread. | |
-.TP | |
.BR sharpen \ [-i] | |
Creates a sharpen kernel. If | |
.B -i | |
is used, an intensified sharpen kernel is created. | |
.TP | |
-.RI \fBgaussian\fP\ [-s\ spread ]\ [-u]\ standard-deviation | |
-Creates a Gaussian blur kernel with the standard deviation | |
-.IR standard-deviation . | |
-If | |
-.B -u | |
-is used, the a Gaussian unsharpen kernel is created. If | |
-.B -s | |
-is specified, the specified | |
-.I spread | |
-will be used, otherwise the spread will be selected automatically. | |
+.BI sobel\ direction | |
+Create a Sobel operator kernel with the specified | |
+.IR direction . | |
+The | |
+.I direction | |
+must be | |
+.BR N | |
+or | |
+.BR H ; | |
+.BR NW | |
+or | |
+.BR WN ; | |
+.BR W | |
+or | |
+.BR V ; | |
+.BR SW | |
+or | |
+.BR WS ; | |
+.BR S ; | |
+.BR SE | |
+or | |
+.BR ES ; | |
+.BR E ; | |
+.BR NE | |
+or | |
+.BR EN . | |
.SH OPTIONS | |
.TP | |
.B -a | |
diff --git a/src/blind-kernel.c b/src/blind-kernel.c | |
@@ -5,9 +5,13 @@ USAGE("[-xyza] kernel [parameter] ...") | |
#define SUBUSAGE(FORMAT) "usage: %s [-xyza] " FORMAT "\n", argv0 | |
#define STRCASEEQ3(A, B1, B2, B3) (!strcasecmp(A, B1) || !strcasecmp(A, B2) ||… | |
+#define STRCASEEQ2(A, B1, B2) (!strcasecmp(A, B1) || !strcasecmp(A, B2)) | |
#define LIST_KERNELS\ | |
X(kernel_kirsch, "kirsch")\ | |
+ X(kernel_gradient, "gradient")\ | |
+ X(kernel_sobel, "sobel")\ | |
+ X(kernel_emboss, "emboss")\ | |
X(kernel_box_blur, "box blur")\ | |
X(kernel_sharpen, "sharpen")\ | |
X(kernel_gaussian, "gaussian") | |
@@ -42,6 +46,95 @@ kernel_kirsch(int argc, char *argv[], size_t *rows, size_t *… | |
} | |
static const double * | |
+kernel_gradient(int argc, char *argv[], size_t *rows, size_t *cols, double **f… | |
+{ | |
+ static const double matrices[][9] = { | |
+ { 1, 1, 1, 0, 0, 0, -1, -1, -1}, | |
+ { 1, 1, 0, 1, 0, -1, 0, -1, -1}, | |
+ { 1, 0, -1, 1, 0, -1, 1, 0, -1}, | |
+ { 0, -1, -1, 1, 0, -1, 1, 1, 0}, | |
+ {-1, -1, -1, 0, 0, 0, 1, 1, 1}, | |
+ {-1, -1, 0, -1, 0, 1, 0, 1, 1}, | |
+ {-1, 0, 1, -1, 0, 1, -1, 0, 1}, | |
+ { 0, 1, 1, -1, 0, 1, -1, -1, 0}, | |
+ }; | |
+ *free_this = NULL; | |
+ *rows = *cols = 3; | |
+ if (argc != 1) | |
+ eprintf(SUBUSAGE("'gradient' direction")); | |
+ if (STRCASEEQ2(argv[0], "N", "N")) return matrices[0]; | |
+ if (STRCASEEQ2(argv[0], "NW", "WN")) return matrices[1]; | |
+ if (STRCASEEQ2(argv[0], "W", "W")) return matrices[2]; | |
+ if (STRCASEEQ2(argv[0], "SW", "WS")) return matrices[3]; | |
+ if (STRCASEEQ2(argv[0], "S", "H")) return matrices[4]; | |
+ if (STRCASEEQ2(argv[0], "SE", "ES")) return matrices[5]; | |
+ if (STRCASEEQ2(argv[0], "E", "V")) return matrices[6]; | |
+ if (STRCASEEQ2(argv[0], "NE", "EN")) return matrices[7]; | |
+ eprintf("unrecognised direction: %s\n", argv[0]); | |
+ return NULL; | |
+} | |
+ | |
+static const double * | |
+kernel_sobel(int argc, char *argv[], size_t *rows, size_t *cols, double **free… | |
+{ | |
+ static const double matrices[][9] = { | |
+ { 1, 2, 1, 0, 0, 0, -1, -2, -1}, | |
+ { 2, 1, 0, 1, 0, -1, 0, -1, -2}, | |
+ { 1, 0, -1, 2, 0, -2, 1, 0, -1}, | |
+ { 0, -1, -2, 1, 0, -1, 2, 1, 0}, | |
+ {-1, -2, -1, 0, 0, 0, 1, 2, 1}, | |
+ {-2, -1, 0, -1, 0, 1, 0, 1, 2}, | |
+ {-1, 0, 1, -2, 0, 2, -1, 0, 1}, | |
+ { 0, 1, 2, -1, 0, 1, -2, -1, 0}, | |
+ }; | |
+ *free_this = NULL; | |
+ *rows = *cols = 3; | |
+ if (argc != 1) | |
+ eprintf(SUBUSAGE("'sobel' direction")); | |
+ if (STRCASEEQ2(argv[0], "N", "H")) return matrices[0]; | |
+ if (STRCASEEQ2(argv[0], "NW", "WN")) return matrices[1]; | |
+ if (STRCASEEQ2(argv[0], "W", "V")) return matrices[2]; | |
+ if (STRCASEEQ2(argv[0], "SW", "WS")) return matrices[3]; | |
+ if (STRCASEEQ2(argv[0], "S", "S")) return matrices[4]; | |
+ if (STRCASEEQ2(argv[0], "SE", "ES")) return matrices[5]; | |
+ if (STRCASEEQ2(argv[0], "E", "E")) return matrices[6]; | |
+ if (STRCASEEQ2(argv[0], "NE", "EN")) return matrices[7]; | |
+ eprintf("unrecognised direction: %s\n", argv[0]); | |
+ return NULL; | |
+} | |
+ | |
+static const double * | |
+kernel_emboss(int argc, char *argv[], size_t *rows, size_t *cols, double **fre… | |
+{ | |
+ static const double matrices[][9] = { | |
+ { 1, 2, 1, 0, 1, 0, -1, -2, -1}, | |
+ { 2, 1, 0, 1, 1, -1, 0, -1, -2}, | |
+ { 1, 0, -1, 2, 1, -2, 1, 0, -1}, | |
+ { 0, -1, -2, 1, 1, -1, 2, 1, 0}, | |
+ {-1, -2, -1, 0, 1, 0, 1, 2, 1}, | |
+ {-2, -1, 0, -1, 1, 1, 0, 1, 2}, | |
+ {-1, 0, 1, -2, 1, 2, -1, 0, 1}, | |
+ { 0, 1, 2, -1, 1, 1, -2, -1, 0}, | |
+ }; | |
+ *free_this = NULL; | |
+ *rows = *cols = 3; | |
+ if (argc > 1) | |
+ eprintf(SUBUSAGE("'emboss' [direction]")); | |
+ if (!argc) | |
+ return matrices[5]; | |
+ if (STRCASEEQ2(argv[0], "N", "N")) return matrices[0]; | |
+ if (STRCASEEQ2(argv[0], "NW", "WN")) return matrices[1]; | |
+ if (STRCASEEQ2(argv[0], "W", "W")) return matrices[2]; | |
+ if (STRCASEEQ2(argv[0], "SW", "WS")) return matrices[3]; | |
+ if (STRCASEEQ2(argv[0], "S", "S")) return matrices[4]; | |
+ if (STRCASEEQ2(argv[0], "SE", "ES")) return matrices[5]; | |
+ if (STRCASEEQ2(argv[0], "E", "E")) return matrices[6]; | |
+ if (STRCASEEQ2(argv[0], "NE", "EN")) return matrices[7]; | |
+ eprintf("unrecognised direction: %s\n", argv[0]); | |
+ return NULL; | |
+} | |
+ | |
+static const double * | |
kernel_box_blur(int argc, char *argv[], size_t *rows, size_t *cols, double **f… | |
{ | |
size_t sx = 1, sy = 1, i, n; | |
@@ -191,11 +284,6 @@ usage: | |
Edge detection: MATRIX(-1, -1, -1, -1, 8, -1, -1, -1, -1) | |
Edge detection: MATRIX( 0, 0, 0, -1, 2, -1, 0, 0, 0) [H] | |
Edge detection: MATRIX( 0, -1, 0, 0, 2, 0, 0, -1, 0) [V] | |
- Gradient detection: MATRIX(-1, -1, -1, 0, 0, 0, 1, 1, 1) [H] | |
- Gradient detection: MATRIX(-1, 0, 1, -1, 0, 1, -1, 0, 1) [V] | |
- Sobel operator: MATRIX( 1, 2, 1, 0, 0, 0, -1, -2, -1) [H] | |
- Sobel operator: MATRIX( 1, 0, -1, 2, 0, -2, 1, 0, -1) [V] | |
- Emboss: MATRIX(-2, -1, 0, -1, 1, 1, 0, 1, 2) | |
Edge enhance: MATRIX( 0, 0, 0, -1, 1, 0, 0, 0, 0) | |
*/ | |