commit a79568e8ab6bd516bef02e87855c23526356f20a
Author:     Mattias Andrée <[email protected]>
AuthorDate: Wed Jul 26 17:50:58 2017 +0200
Commit:     Mattias Andrée <[email protected]>
CommitDate: Wed Jul 26 17:50:58 2017 +0200

    blind-kernel: add more kernels
    
    Signed-off-by: Mattias Andrée <[email protected]>

diff --git a/man/blind-kernel.1 b/man/blind-kernel.1
index df789cc..5083e75 100644
--- 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
index ae66b24..f670886 100644
--- 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) || 
!strcasecmp(A, B3))
+#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 
*cols, double **free_
 }
 
 static const double *
+kernel_gradient(int argc, char *argv[], size_t *rows, size_t *cols, double 
**free_this)
+{
+       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_this)
+{
+       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 
**free_this)
+{
+       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 
**free_this)
 {
        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)
  */
 

Reply via email to