URI: 
       blind-kernel: add more kernels - blind - suckless command-line video editing utility
  HTML git clone git://git.suckless.org/blind
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit a79568e8ab6bd516bef02e87855c23526356f20a
   DIR parent ffeba5cae6ebf01f421e11eee2c4d050da0bb3f3
  HTML Author: Mattias Andrée <maandree@kth.se>
       Date:   Wed, 26 Jul 2017 17:50:58 +0200
       
       blind-kernel: add more kernels
       
       Signed-off-by: Mattias Andrée <maandree@kth.se>
       
       Diffstat:
         M man/blind-kernel.1                  |     128 +++++++++++++++++++++++++------
         M src/blind-kernel.c                  |      98 +++++++++++++++++++++++++++++--
       
       2 files changed, 198 insertions(+), 28 deletions(-)
       ---
   DIR 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
   DIR 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) || !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)
         */