URI: 
       Add glow effects - 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 5ba5815d0a7255f311cdc66251774e6e36854e8f
   DIR parent eebc4d5fb9cf6d78cbdba7a5aa9be713ddf9959c
  HTML Author: Mattias Andrée <maandree@kth.se>
       Date:   Wed, 26 Jul 2017 19:25:28 +0200
       
       Add glow effects
       
       Signed-off-by: Mattias Andrée <maandree@kth.se>
       
       Diffstat:
         M TODO                                |       2 +-
         M man/blind-gauss-blur.1              |       9 +++++++--
         M man/blind-kernel.1                  |       8 ++++++--
         M src/blind-gauss-blur.c              |      33 ++++++++++++++++++++++++++++++-
         M src/blind-kernel.c                  |      11 ++++++++---
       
       5 files changed, 54 insertions(+), 9 deletions(-)
       ---
   DIR diff --git a/TODO b/TODO
       @@ -43,7 +43,7 @@ blind-from-video: add options to:
        
        blind-cone-gradient: add ability to make gradient superelliptic
        
       -Add [-j jobs] to blind-from-video and blind-to-video.
       +Add [-j jobs] to blind-from-video, blind-to-video, and blind-apply-kernel.
        
        long double is slightly faster than long.
        long double (xyza q) could be added as another format.
   DIR diff --git a/man/blind-gauss-blur.1 b/man/blind-gauss-blur.1
       @@ -10,7 +10,7 @@ blind-gauss-blur - Apply Gaussian blur to a video
        |
        -s
        .RB ' auto ']
       -[-achvy]
       +[-acghvy]
        .I sd-stream
        .SH DESCRIPTION
        .B blind-gauss-blur
       @@ -45,6 +45,9 @@ video is opaque.
        .B -c
        Blur the chroma only, not the luma.
        .TP
       +.B -g
       +Add glow effect.
       +.TP
        .B -h
        Blur horizontally only. Has no affect if -v is also
        specified.
       @@ -75,7 +78,9 @@ as the standard deviation all channels.
        .SH REQUIREMENTS
        .B blind-gauss-blur
        requires enough free memory to load three full frames into
       -memory. A frame requires 32 bytes per pixel it contains.
       +memory. A frame requires 32 bytes per pixel it contains. If
       +.B -g
       +is used, four full frames are required.
        .SH SEE ALSO
        .BR blind (7),
        .BR blind-single-colour (1),
   DIR diff --git a/man/blind-kernel.1 b/man/blind-kernel.1
       @@ -61,12 +61,16 @@ is specified,
        .B SE
        is used.
        .TP
       -.RI \fBgaussian\fP\ [-s\  spread ]\ [-u]\  standard-deviation
       +.RI \fBgaussian\fP\ [-s\  spread ]\ [-g\ |\ -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
       +is used, the a Gaussian unsharpen kernel is created.
       +If
       +.B -g
       +is used, the a Gaussian blur kernel with glow effect is created.
       +If
        .B -s
        is specified, the specified
        .I spread
   DIR diff --git a/src/blind-gauss-blur.c b/src/blind-gauss-blur.c
       @@ -1,16 +1,18 @@
        /* See LICENSE file for copyright and license details. */
        #include "common.h"
        
       -USAGE("[-j jobs] [-s spread | -s 'auto'] [-achvy] sd-stream")
       +USAGE("[-j jobs] [-s spread | -s 'auto'] [-acghvy] sd-stream")
        
        static int chroma = 0;
        static int noalpha = 0;
       +static int glow = 0;
        static int vertical = 0;
        static int horizontal = 0;
        static int measure_y_only = 0;
        static int auto_spread = 0;
        static size_t jobs = 1;
        static size_t spread = 0;
       +static void *original = NULL;
        
        /*
         * This is not a regular simple gaussian blur implementation.
       @@ -126,6 +128,7 @@ static size_t spread = 0;
                        \
                        pixel_t *restrict clr = (pixel_t *)cbuf;\
                        pixel_t *restrict sig = (pixel_t *)sbuf;\
       +                pixel_t *restrict orig = original;\
                        pixel_t *img = (pixel_t *)output;\
                        pixel_t c, k;\
                        size_t x1, y1, i1, x2, y2, i2;\
       @@ -139,6 +142,8 @@ static size_t spread = 0;
                        x2end = colour->width;\
                        y2end = colour->height;\
                        \
       +                if (glow)\
       +                        memcpy(orig, clr, colour->frame_size);\
                        if (chroma || !noalpha) {\
                                start = 0, end = colour->height;\
                                is_master = efork_jobs(&start, &end, jobs, &children);\
       @@ -155,6 +160,12 @@ static size_t spread = 0;
                                        }\
                                }\
                                \
       +                        /* store original image */\
       +                        if (glow) {\
       +                                i1 = start * colour->width;\
       +                                memcpy(orig + i1, clr + i1, (end - start) * colour->width * sizeof(*clr));\
       +                        }\
       +                        \
                                /* convert colour model */\
                                if (chroma) {\
                                        i1 = start * colour->width;\
       @@ -247,6 +258,19 @@ static size_t spread = 0;
                                }\
                        }\
                        \
       +                /* apply glow */\
       +                if (glow) {\
       +                        i1 = start * colour->width;\
       +                        for (y1 = start; y1 < end; y1++) {\
       +                                for (x1 = 0; x1 < colour->width; x1++, i1++) {\
       +                                        img[i1][0] = 1 - (1 - img[i1][0]) * (1 - orig[i1][0]);\
       +                                        img[i1][1] = 1 - (1 - img[i1][1]) * (1 - orig[i1][1]);\
       +                                        img[i1][2] = 1 - (1 - img[i1][2]) * (1 - orig[i1][2]);\
       +                                        img[i1][3] = 1 - (1 - img[i1][3]) * (1 - orig[i1][3]);\
       +                                }\
       +                        }\
       +                }\
       +                \
                        /* unpremultiply alpha channel */\
                        i1 = start * colour->width;\
                        for (y1 = start; y1 < end; y1++) {\
       @@ -301,6 +325,9 @@ main(int argc, char *argv[])
                case 'c':
                        chroma = 1;
                        break;
       +        case 'g':
       +                glow = 1;
       +                break;
                case 'h':
                        horizontal = 1;
                        break;
       @@ -340,8 +367,12 @@ main(int argc, char *argv[])
                if (jobs > colour.height)
                        jobs = colour.height;
        
       +        if (glow)
       +                original = emalloc(colour.frame_size);
       +
                fprint_stream_head(stdout, &colour);
                efflush(stdout, "<stdout>");
                process_each_frame_two_streams(&colour, &sigma, STDOUT_FILENO, "<stdout>", process);
       +        free(original);
                return 0;
        }
   DIR diff --git a/src/blind-kernel.c b/src/blind-kernel.c
       @@ -223,13 +223,16 @@ kernel_gaussian(int argc, char *argv[], size_t *rows, size_t *cols, double **fre
        {
                size_t spread = 0, y, x;
                ssize_t xx, yy;
       -        int unsharpen = 0;
       +        int unsharpen = 0, glow = 0;
                double sigma, value, c, k;
                char *arg;
        
        #define argv0 arg
                argc++, argv--;
                ARGBEGIN {
       +        case 'g':
       +                glow = 1;
       +                break;
                case 's':
                        if (!(arg = ARGF()))
                                goto usage;
       @@ -243,7 +246,7 @@ kernel_gaussian(int argc, char *argv[], size_t *rows, size_t *cols, double **fre
                } ARGEND;
        #undef argv0
        
       -        if (argc != 1)
       +        if (argc != 1 || (unsharpen && glow))
                        goto usage;
        
                sigma = etolf_arg("standard-deviation", argv[0]);
       @@ -270,11 +273,13 @@ kernel_gaussian(int argc, char *argv[], size_t *rows, size_t *cols, double **fre
        
                if (unsharpen)
                        (*free_this)[spread * *cols + spread] -= 2.0;
       +        if (glow)
       +                (*free_this)[spread * *cols + spread] += 1;
        
                return *free_this;
        
        usage:
       -        eprintf(SUBUSAGE("'gaussian' [-s spread] [-u] standard-deviation"));
       +        eprintf(SUBUSAGE("'gaussian' [-s spread] [-g | -u] standard-deviation"));
                return NULL;
        }