Flutter Engine
The Flutter Engine
third_party
skia
src
core
SkGaussFilter.cpp
Go to the documentation of this file.
1
/*
2
* Copyright 2017 Google Inc.
3
*
4
* Use of this source code is governed by a BSD-style license that can be
5
* found in the LICENSE file.
6
*/
7
8
#include "
src/core/SkGaussFilter.h
"
9
10
#include "
include/private/base/SkAssert.h
"
11
12
#include <cmath>
13
14
// The value when we can stop expanding the filter. The spec implies that 3% is acceptable, but
15
// we just use 1%.
16
static
constexpr
double
kGoodEnough
= 1.0 / 100.0;
17
18
// Normalize the values of gauss to 1.0, and make sure they add to one.
19
// NB if n == 1, then this will force gauss[0] == 1.
20
static
void
normalize
(
int
n,
double
* gauss) {
21
// Carefully add from smallest to largest to calculate the normalizing sum.
22
double
sum = 0;
23
for
(
int
i
= n-1;
i
>= 1;
i
--) {
24
sum += 2 * gauss[
i
];
25
}
26
sum += gauss[0];
27
28
// Normalize gauss.
29
for
(
int
i
= 0;
i
< n;
i
++) {
30
gauss[
i
] /= sum;
31
}
32
33
// The factors should sum to 1. Take any remaining slop, and add it to gauss[0]. Add the
34
// values in such a way to maintain the most accuracy.
35
sum = 0;
36
for
(
int
i
= n - 1;
i
>= 1;
i
--) {
37
sum += 2 * gauss[
i
];
38
}
39
40
gauss[0] = 1 - sum;
41
}
42
43
static
int
calculate_bessel_factors
(
double
sigma,
double
*gauss) {
44
auto
var = sigma * sigma;
45
46
// The two functions below come from the equations in "Handbook of Mathematical Functions"
47
// by Abramowitz and Stegun. Specifically, equation 9.6.10 on page 375. Bessel0 is given
48
// explicitly as 9.6.12
49
// BesselI_0 for 0 <= sigma < 2.
50
// NB the k = 0 factor is just sum = 1.0.
51
auto
besselI_0 = [](
double
t) ->
double
{
52
auto
tSquaredOver4 = t * t / 4.0;
53
auto
sum = 1.0;
54
auto
factor = 1.0;
55
auto
k = 1;
56
// Use a variable number of loops. When sigma is small, this only requires 3-4 loops, but
57
// when sigma is near 2, it could require 10 loops. The same holds for BesselI_1.
58
while
(factor > 1.0/1000000.0) {
59
factor *= tSquaredOver4 / (k * k);
60
sum += factor;
61
k += 1;
62
}
63
return
sum;
64
};
65
// BesselI_1 for 0 <= sigma < 2.
66
auto
besselI_1 = [](
double
t) ->
double
{
67
auto
tSquaredOver4 = t * t / 4.0;
68
auto
sum = t / 2.0;
69
auto
factor = sum;
70
auto
k = 1;
71
while
(factor > 1.0/1000000.0) {
72
factor *= tSquaredOver4 / (k * (k + 1));
73
sum += factor;
74
k += 1;
75
}
76
return
sum;
77
};
78
79
// The following formula for calculating the Gaussian kernel is from
80
// "Scale-Space for Discrete Signals" by Tony Lindeberg.
81
// gauss(n; var) = besselI_n(var) / (e^var)
82
auto
d
= std::exp(var);
83
double
b
[
SkGaussFilter::kGaussArrayMax
] = {besselI_0(var), besselI_1(var)};
84
gauss[0] =
b
[0]/
d
;
85
gauss[1] =
b
[1]/
d
;
86
87
// The code below is tricky, and written to mirror the recursive equations from the book.
88
// The maximum spread for sigma == 2 is guass[4], but in order to know to stop guass[5]
89
// is calculated. At this point n == 5 meaning that gauss[0..4] are the factors, but a 6th
90
// element was used to calculate them.
91
int
n = 1;
92
// The recurrence relation below is from "Numerical Recipes" 3rd Edition.
93
// Equation 6.5.16 p.282
94
while
(gauss[n] >
kGoodEnough
) {
95
b
[n+1] = -(2*n/var) *
b
[n] +
b
[n-1];
96
gauss[n+1] =
b
[n+1] /
d
;
97
n += 1;
98
}
99
100
normalize
(n, gauss);
101
102
return
n;
103
}
104
105
SkGaussFilter::SkGaussFilter
(
double
sigma) {
106
SkASSERT
(0 <= sigma && sigma < 2);
107
108
fN =
calculate_bessel_factors
(sigma, fBasis);
109
}
SkAssert.h
SkASSERT
#define SkASSERT(cond)
Definition:
SkAssert.h:116
normalize
static void normalize(int n, double *gauss)
Definition:
SkGaussFilter.cpp:20
kGoodEnough
static constexpr double kGoodEnough
Definition:
SkGaussFilter.cpp:16
calculate_bessel_factors
static int calculate_bessel_factors(double sigma, double *gauss)
Definition:
SkGaussFilter.cpp:43
SkGaussFilter.h
SkGaussFilter::SkGaussFilter
SkGaussFilter(double sigma)
Definition:
SkGaussFilter.cpp:105
SkGaussFilter::kGaussArrayMax
static constexpr int kGaussArrayMax
Definition:
SkGaussFilter.h:17
d
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition:
main.cc:19
b
static bool b
Definition:
ffi_native_test_module.c:74
i
int i
Definition:
fl_socket_accessible.cc:18
Generated on Sun Jun 23 2024 21:56:12 for Flutter Engine by
1.9.4