• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2011 Pascal Getreuer
3  * Copyright (c) 2016 Paul B Mahol
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above
11  *    copyright notice, this list of conditions and the following
12  *    disclaimer in the documentation and/or other materials provided
13  *    with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19  * HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef AVFILTER_GBLUR_INIT_H
29 #define AVFILTER_GBLUR_INIT_H
30 
31 #include "config.h"
32 #include "libavutil/attributes.h"
33 #include "libavutil/common.h"
34 #include "gblur.h"
35 
postscale_c(float * buffer,int length,float postscale,float min,float max)36 static void postscale_c(float *buffer, int length,
37                         float postscale, float min, float max)
38 {
39     for (int i = 0; i < length; i++) {
40         buffer[i] *= postscale;
41         buffer[i] = av_clipf(buffer[i], min, max);
42     }
43 }
44 
horiz_slice_c(float * buffer,int width,int height,int steps,float nu,float bscale,float * localbuf)45 static void horiz_slice_c(float *buffer, int width, int height, int steps,
46                           float nu, float bscale, float *localbuf)
47 {
48     int x;
49     for (int y = 0; y < height; y++) {
50         for (int step = 0; step < steps; step++) {
51             float *ptr = buffer + width * y;
52             ptr[0] *= bscale;
53 
54             /* Filter rightwards */
55             for (x = 1; x < width; x++)
56                 ptr[x] += nu * ptr[x - 1];
57             ptr[x = width - 1] *= bscale;
58 
59             /* Filter leftwards */
60             for (; x > 0; x--)
61                 ptr[x - 1] += nu * ptr[x];
62         }
63     }
64 }
65 
do_vertical_columns(float * buffer,int width,int height,int column_begin,int column_end,int steps,float nu,float boundaryscale,int column_step)66 static void do_vertical_columns(float *buffer, int width, int height,
67                                 int column_begin, int column_end, int steps,
68                                 float nu, float boundaryscale, int column_step)
69 {
70     const int numpixels = width * height;
71     int i;
72     for (int x = column_begin; x < column_end;) {
73         for (int step = 0; step < steps; step++) {
74             float *ptr = buffer + x;
75             for (int k = 0; k < column_step; k++) {
76                 ptr[k] *= boundaryscale;
77             }
78             /* Filter downwards */
79             for (i = width; i < numpixels; i += width) {
80                 for (int k = 0; k < column_step; k++) {
81                     ptr[i + k] += nu * ptr[i - width + k];
82                 }
83             }
84             i = numpixels - width;
85 
86             for (int k = 0; k < column_step; k++)
87                 ptr[i + k] *= boundaryscale;
88 
89             /* Filter upwards */
90             for (; i > 0; i -= width) {
91                 for (int k = 0; k < column_step; k++)
92                     ptr[i - width + k] += nu * ptr[i + k];
93             }
94         }
95         x += column_step;
96     }
97 }
98 
verti_slice_c(float * buffer,int width,int height,int slice_start,int slice_end,int steps,float nu,float boundaryscale)99 static void verti_slice_c(float *buffer, int width, int height,
100                           int slice_start, int slice_end, int steps,
101                           float nu, float boundaryscale)
102 {
103     int aligned_end = slice_start + (((slice_end - slice_start) >> 3) << 3);
104     /* Filter vertically along columns (process 8 columns in each step) */
105     do_vertical_columns(buffer, width, height, slice_start, aligned_end,
106                         steps, nu, boundaryscale, 8);
107     /* Filter un-aligned columns one by one */
108     do_vertical_columns(buffer, width, height, aligned_end, slice_end,
109                         steps, nu, boundaryscale, 1);
110 }
111 
ff_gblur_init(GBlurContext * s)112 static av_unused void ff_gblur_init(GBlurContext *s)
113 {
114     s->localbuf = NULL;
115     s->horiz_slice = horiz_slice_c;
116     s->verti_slice = verti_slice_c;
117     s->postscale_slice = postscale_c;
118 #if ARCH_X86
119     ff_gblur_init_x86(s);
120 #endif
121 }
122 
123 #endif /* AVFILTER_GBLUR_INIT_H */
124