glur 1.1.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -8
- package/lib/blur_mono16.d.ts +6 -0
- package/lib/blur_mono16.mjs +116 -0
- package/lib/blur_rgba.d.ts +6 -0
- package/lib/blur_rgba.mjs +193 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.mjs +2 -0
- package/package.json +15 -5
- package/CHANGELOG.md +0 -29
- package/index.js +0 -196
- package/mono16.js +0 -119
package/README.md
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
glur
|
|
2
2
|
====
|
|
3
3
|
|
|
4
|
-
[](https://travis-ci.org/nodeca/glur)
|
|
5
4
|
[](https://www.npmjs.org/package/glur)
|
|
6
5
|
|
|
7
|
-
> Fast Gaussian Blur in pure JavaScript, via IIR
|
|
6
|
+
> Fast Gaussian Blur in pure JavaScript, via IIR filter. Speed does not depend on
|
|
8
7
|
> blur radius.
|
|
9
8
|
|
|
10
9
|
__[demo 1](http://nodeca.github.io/glur/demo)__,
|
|
@@ -15,23 +14,28 @@ Install
|
|
|
15
14
|
-------
|
|
16
15
|
|
|
17
16
|
```bash
|
|
18
|
-
npm install glur
|
|
17
|
+
npm install glur
|
|
19
18
|
```
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
API
|
|
23
22
|
---
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
```js
|
|
25
|
+
import { blurRGBA, blurMono16 } from 'glur'
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### blurRGBA(src, width, height, radius)
|
|
26
29
|
|
|
27
|
-
- __src__ -
|
|
30
|
+
- __src__ - `Uint8ClampedArray` or `Uint8Array` with RGBA image data (modified in place).
|
|
28
31
|
- __width__ - image width.
|
|
29
32
|
- __height__ - image height.
|
|
30
33
|
- __radius__ - blur radius.
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
### blurMono16(src, width, height, radius)
|
|
36
|
+
|
|
37
|
+
Same as above, but input is a grayscale `Uint16Array`. Useful for unsharp mask
|
|
38
|
+
via brightness/lightness channel.
|
|
35
39
|
|
|
36
40
|
|
|
37
41
|
Authors
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// Calculate Gaussian blur of an image using IIR filter
|
|
2
|
+
// The method is taken from Intel's white paper and code example attached to it:
|
|
3
|
+
// https://software.intel.com/en-us/articles/iir-gaussian-blur-filter
|
|
4
|
+
// -implementation-using-intel-advanced-vector-extensions
|
|
5
|
+
|
|
6
|
+
function gaussCoef (sigma) {
|
|
7
|
+
if (sigma < 0.5) {
|
|
8
|
+
sigma = 0.5
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const a = Math.exp(0.726 * 0.726) / sigma,
|
|
12
|
+
g1 = Math.exp(-a),
|
|
13
|
+
g2 = Math.exp(-2 * a),
|
|
14
|
+
k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2)
|
|
15
|
+
|
|
16
|
+
const a0 = k
|
|
17
|
+
const a1 = k * (a - 1) * g1
|
|
18
|
+
const a2 = k * (a + 1) * g1
|
|
19
|
+
const a3 = -k * g2
|
|
20
|
+
const b1 = 2 * g1
|
|
21
|
+
const b2 = -g2
|
|
22
|
+
const left_corner = (a0 + a1) / (1 - b1 - b2)
|
|
23
|
+
const right_corner = (a2 + a3) / (1 - b1 - b2)
|
|
24
|
+
|
|
25
|
+
// Attempt to force type to FP32.
|
|
26
|
+
return new Float32Array([a0, a1, a2, a3, b1, b2, left_corner, right_corner])
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function convolveMono16 (src, out, line, coeff, width, height) {
|
|
30
|
+
// takes src image and writes the blurred and transposed result into out
|
|
31
|
+
|
|
32
|
+
let prev_src, curr_src, curr_out, prev_out, prev_prev_out
|
|
33
|
+
let src_index, out_index, line_index
|
|
34
|
+
let i, j
|
|
35
|
+
let coeff_a0, coeff_a1, coeff_b1, coeff_b2
|
|
36
|
+
|
|
37
|
+
for (i = 0; i < height; i++) {
|
|
38
|
+
src_index = i * width
|
|
39
|
+
out_index = i
|
|
40
|
+
line_index = 0
|
|
41
|
+
|
|
42
|
+
// left to right
|
|
43
|
+
prev_src = src[src_index]
|
|
44
|
+
prev_prev_out = prev_src * coeff[6]
|
|
45
|
+
prev_out = prev_prev_out
|
|
46
|
+
|
|
47
|
+
coeff_a0 = coeff[0]
|
|
48
|
+
coeff_a1 = coeff[1]
|
|
49
|
+
coeff_b1 = coeff[4]
|
|
50
|
+
coeff_b2 = coeff[5]
|
|
51
|
+
|
|
52
|
+
for (j = 0; j < width; j++) {
|
|
53
|
+
curr_src = src[src_index]
|
|
54
|
+
|
|
55
|
+
curr_out = curr_src * coeff_a0 +
|
|
56
|
+
prev_src * coeff_a1 +
|
|
57
|
+
prev_out * coeff_b1 +
|
|
58
|
+
prev_prev_out * coeff_b2
|
|
59
|
+
|
|
60
|
+
prev_prev_out = prev_out
|
|
61
|
+
prev_out = curr_out
|
|
62
|
+
prev_src = curr_src
|
|
63
|
+
|
|
64
|
+
line[line_index] = prev_out
|
|
65
|
+
line_index++
|
|
66
|
+
src_index++
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
src_index--
|
|
70
|
+
line_index--
|
|
71
|
+
out_index += height * (width - 1)
|
|
72
|
+
|
|
73
|
+
// right to left
|
|
74
|
+
prev_src = src[src_index]
|
|
75
|
+
prev_prev_out = prev_src * coeff[7]
|
|
76
|
+
prev_out = prev_prev_out
|
|
77
|
+
curr_src = prev_src
|
|
78
|
+
|
|
79
|
+
coeff_a0 = coeff[2]
|
|
80
|
+
coeff_a1 = coeff[3]
|
|
81
|
+
|
|
82
|
+
for (j = width - 1; j >= 0; j--) {
|
|
83
|
+
curr_out = curr_src * coeff_a0 +
|
|
84
|
+
prev_src * coeff_a1 +
|
|
85
|
+
prev_out * coeff_b1 +
|
|
86
|
+
prev_prev_out * coeff_b2
|
|
87
|
+
|
|
88
|
+
prev_prev_out = prev_out
|
|
89
|
+
prev_out = curr_out
|
|
90
|
+
|
|
91
|
+
prev_src = curr_src
|
|
92
|
+
curr_src = src[src_index]
|
|
93
|
+
|
|
94
|
+
out[out_index] = line[line_index] + prev_out
|
|
95
|
+
|
|
96
|
+
src_index--
|
|
97
|
+
line_index--
|
|
98
|
+
out_index -= height
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function blurMono16 (src, width, height, radius) {
|
|
104
|
+
// Quick exit on zero radius
|
|
105
|
+
if (!radius) { return }
|
|
106
|
+
|
|
107
|
+
const out = new Uint16Array(src.length),
|
|
108
|
+
tmp_line = new Float32Array(Math.max(width, height))
|
|
109
|
+
|
|
110
|
+
const coeff = gaussCoef(radius)
|
|
111
|
+
|
|
112
|
+
convolveMono16(src, out, tmp_line, coeff, width, height, radius)
|
|
113
|
+
convolveMono16(out, src, tmp_line, coeff, height, width, radius)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export default blurMono16
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// Calculate Gaussian blur of an image using IIR filter
|
|
2
|
+
// The method is taken from Intel's white paper and code example attached to it:
|
|
3
|
+
// https://software.intel.com/en-us/articles/iir-gaussian-blur-filter
|
|
4
|
+
// -implementation-using-intel-advanced-vector-extensions
|
|
5
|
+
|
|
6
|
+
function gaussCoef (sigma) {
|
|
7
|
+
if (sigma < 0.5) {
|
|
8
|
+
sigma = 0.5
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const a = Math.exp(0.726 * 0.726) / sigma,
|
|
12
|
+
g1 = Math.exp(-a),
|
|
13
|
+
g2 = Math.exp(-2 * a),
|
|
14
|
+
k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2)
|
|
15
|
+
|
|
16
|
+
const a0 = k
|
|
17
|
+
const a1 = k * (a - 1) * g1
|
|
18
|
+
const a2 = k * (a + 1) * g1
|
|
19
|
+
const a3 = -k * g2
|
|
20
|
+
const b1 = 2 * g1
|
|
21
|
+
const b2 = -g2
|
|
22
|
+
const left_corner = (a0 + a1) / (1 - b1 - b2)
|
|
23
|
+
const right_corner = (a2 + a3) / (1 - b1 - b2)
|
|
24
|
+
|
|
25
|
+
// Attempt to force type to FP32.
|
|
26
|
+
return new Float32Array([a0, a1, a2, a3, b1, b2, left_corner, right_corner])
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function convolveRGBA (src, out, line, coeff, width, height) {
|
|
30
|
+
// takes src image and writes the blurred and transposed result into out
|
|
31
|
+
|
|
32
|
+
let rgba
|
|
33
|
+
let prev_src_r, prev_src_g, prev_src_b, prev_src_a
|
|
34
|
+
let curr_src_r, curr_src_g, curr_src_b, curr_src_a
|
|
35
|
+
let curr_out_r, curr_out_g, curr_out_b, curr_out_a
|
|
36
|
+
let prev_out_r, prev_out_g, prev_out_b, prev_out_a
|
|
37
|
+
let prev_prev_out_r, prev_prev_out_g, prev_prev_out_b, prev_prev_out_a
|
|
38
|
+
|
|
39
|
+
let src_index, out_index, line_index
|
|
40
|
+
let i, j
|
|
41
|
+
let coeff_a0, coeff_a1, coeff_b1, coeff_b2
|
|
42
|
+
|
|
43
|
+
for (i = 0; i < height; i++) {
|
|
44
|
+
src_index = i * width
|
|
45
|
+
out_index = i
|
|
46
|
+
line_index = 0
|
|
47
|
+
|
|
48
|
+
// left to right
|
|
49
|
+
rgba = src[src_index]
|
|
50
|
+
|
|
51
|
+
prev_src_r = rgba & 0xff
|
|
52
|
+
prev_src_g = (rgba >> 8) & 0xff
|
|
53
|
+
prev_src_b = (rgba >> 16) & 0xff
|
|
54
|
+
prev_src_a = (rgba >> 24) & 0xff
|
|
55
|
+
|
|
56
|
+
prev_prev_out_r = prev_src_r * coeff[6]
|
|
57
|
+
prev_prev_out_g = prev_src_g * coeff[6]
|
|
58
|
+
prev_prev_out_b = prev_src_b * coeff[6]
|
|
59
|
+
prev_prev_out_a = prev_src_a * coeff[6]
|
|
60
|
+
|
|
61
|
+
prev_out_r = prev_prev_out_r
|
|
62
|
+
prev_out_g = prev_prev_out_g
|
|
63
|
+
prev_out_b = prev_prev_out_b
|
|
64
|
+
prev_out_a = prev_prev_out_a
|
|
65
|
+
|
|
66
|
+
coeff_a0 = coeff[0]
|
|
67
|
+
coeff_a1 = coeff[1]
|
|
68
|
+
coeff_b1 = coeff[4]
|
|
69
|
+
coeff_b2 = coeff[5]
|
|
70
|
+
|
|
71
|
+
for (j = 0; j < width; j++) {
|
|
72
|
+
rgba = src[src_index]
|
|
73
|
+
curr_src_r = rgba & 0xff
|
|
74
|
+
curr_src_g = (rgba >> 8) & 0xff
|
|
75
|
+
curr_src_b = (rgba >> 16) & 0xff
|
|
76
|
+
curr_src_a = (rgba >> 24) & 0xff
|
|
77
|
+
|
|
78
|
+
curr_out_r = curr_src_r * coeff_a0 + prev_src_r * coeff_a1 + prev_out_r * coeff_b1 + prev_prev_out_r * coeff_b2
|
|
79
|
+
curr_out_g = curr_src_g * coeff_a0 + prev_src_g * coeff_a1 + prev_out_g * coeff_b1 + prev_prev_out_g * coeff_b2
|
|
80
|
+
curr_out_b = curr_src_b * coeff_a0 + prev_src_b * coeff_a1 + prev_out_b * coeff_b1 + prev_prev_out_b * coeff_b2
|
|
81
|
+
curr_out_a = curr_src_a * coeff_a0 + prev_src_a * coeff_a1 + prev_out_a * coeff_b1 + prev_prev_out_a * coeff_b2
|
|
82
|
+
|
|
83
|
+
prev_prev_out_r = prev_out_r
|
|
84
|
+
prev_prev_out_g = prev_out_g
|
|
85
|
+
prev_prev_out_b = prev_out_b
|
|
86
|
+
prev_prev_out_a = prev_out_a
|
|
87
|
+
|
|
88
|
+
prev_out_r = curr_out_r
|
|
89
|
+
prev_out_g = curr_out_g
|
|
90
|
+
prev_out_b = curr_out_b
|
|
91
|
+
prev_out_a = curr_out_a
|
|
92
|
+
|
|
93
|
+
prev_src_r = curr_src_r
|
|
94
|
+
prev_src_g = curr_src_g
|
|
95
|
+
prev_src_b = curr_src_b
|
|
96
|
+
prev_src_a = curr_src_a
|
|
97
|
+
|
|
98
|
+
line[line_index] = prev_out_r
|
|
99
|
+
line[line_index + 1] = prev_out_g
|
|
100
|
+
line[line_index + 2] = prev_out_b
|
|
101
|
+
line[line_index + 3] = prev_out_a
|
|
102
|
+
line_index += 4
|
|
103
|
+
src_index++
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
src_index--
|
|
107
|
+
line_index -= 4
|
|
108
|
+
out_index += height * (width - 1)
|
|
109
|
+
|
|
110
|
+
// right to left
|
|
111
|
+
rgba = src[src_index]
|
|
112
|
+
|
|
113
|
+
prev_src_r = rgba & 0xff
|
|
114
|
+
prev_src_g = (rgba >> 8) & 0xff
|
|
115
|
+
prev_src_b = (rgba >> 16) & 0xff
|
|
116
|
+
prev_src_a = (rgba >> 24) & 0xff
|
|
117
|
+
|
|
118
|
+
prev_prev_out_r = prev_src_r * coeff[7]
|
|
119
|
+
prev_prev_out_g = prev_src_g * coeff[7]
|
|
120
|
+
prev_prev_out_b = prev_src_b * coeff[7]
|
|
121
|
+
prev_prev_out_a = prev_src_a * coeff[7]
|
|
122
|
+
|
|
123
|
+
prev_out_r = prev_prev_out_r
|
|
124
|
+
prev_out_g = prev_prev_out_g
|
|
125
|
+
prev_out_b = prev_prev_out_b
|
|
126
|
+
prev_out_a = prev_prev_out_a
|
|
127
|
+
|
|
128
|
+
curr_src_r = prev_src_r
|
|
129
|
+
curr_src_g = prev_src_g
|
|
130
|
+
curr_src_b = prev_src_b
|
|
131
|
+
curr_src_a = prev_src_a
|
|
132
|
+
|
|
133
|
+
coeff_a0 = coeff[2]
|
|
134
|
+
coeff_a1 = coeff[3]
|
|
135
|
+
|
|
136
|
+
for (j = width - 1; j >= 0; j--) {
|
|
137
|
+
curr_out_r = curr_src_r * coeff_a0 + prev_src_r * coeff_a1 + prev_out_r * coeff_b1 + prev_prev_out_r * coeff_b2
|
|
138
|
+
curr_out_g = curr_src_g * coeff_a0 + prev_src_g * coeff_a1 + prev_out_g * coeff_b1 + prev_prev_out_g * coeff_b2
|
|
139
|
+
curr_out_b = curr_src_b * coeff_a0 + prev_src_b * coeff_a1 + prev_out_b * coeff_b1 + prev_prev_out_b * coeff_b2
|
|
140
|
+
curr_out_a = curr_src_a * coeff_a0 + prev_src_a * coeff_a1 + prev_out_a * coeff_b1 + prev_prev_out_a * coeff_b2
|
|
141
|
+
|
|
142
|
+
prev_prev_out_r = prev_out_r
|
|
143
|
+
prev_prev_out_g = prev_out_g
|
|
144
|
+
prev_prev_out_b = prev_out_b
|
|
145
|
+
prev_prev_out_a = prev_out_a
|
|
146
|
+
|
|
147
|
+
prev_out_r = curr_out_r
|
|
148
|
+
prev_out_g = curr_out_g
|
|
149
|
+
prev_out_b = curr_out_b
|
|
150
|
+
prev_out_a = curr_out_a
|
|
151
|
+
|
|
152
|
+
prev_src_r = curr_src_r
|
|
153
|
+
prev_src_g = curr_src_g
|
|
154
|
+
prev_src_b = curr_src_b
|
|
155
|
+
prev_src_a = curr_src_a
|
|
156
|
+
|
|
157
|
+
rgba = src[src_index]
|
|
158
|
+
curr_src_r = rgba & 0xff
|
|
159
|
+
curr_src_g = (rgba >> 8) & 0xff
|
|
160
|
+
curr_src_b = (rgba >> 16) & 0xff
|
|
161
|
+
curr_src_a = (rgba >> 24) & 0xff
|
|
162
|
+
|
|
163
|
+
rgba = ((line[line_index] + prev_out_r) << 0) +
|
|
164
|
+
((line[line_index + 1] + prev_out_g) << 8) +
|
|
165
|
+
((line[line_index + 2] + prev_out_b) << 16) +
|
|
166
|
+
((line[line_index + 3] + prev_out_a) << 24)
|
|
167
|
+
|
|
168
|
+
out[out_index] = rgba
|
|
169
|
+
|
|
170
|
+
src_index--
|
|
171
|
+
line_index -= 4
|
|
172
|
+
out_index -= height
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function blurRGBA (src, width, height, radius) {
|
|
178
|
+
// Quick exit on zero radius
|
|
179
|
+
if (!radius) { return }
|
|
180
|
+
|
|
181
|
+
// Unify input data type, to keep convolver calls isomorphic
|
|
182
|
+
const src32 = new Uint32Array(src.buffer)
|
|
183
|
+
|
|
184
|
+
const out = new Uint32Array(src32.length),
|
|
185
|
+
tmp_line = new Float32Array(Math.max(width, height) * 4)
|
|
186
|
+
|
|
187
|
+
const coeff = gaussCoef(radius)
|
|
188
|
+
|
|
189
|
+
convolveRGBA(src32, out, tmp_line, coeff, width, height, radius)
|
|
190
|
+
convolveRGBA(out, src32, tmp_line, coeff, height, width, radius)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export default blurRGBA
|
package/lib/index.d.ts
ADDED
package/lib/index.mjs
ADDED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "glur",
|
|
3
3
|
"description": "Fast Gaussian Blur in pure JavaScript, via IIR filer. Speed does not depend on blur radius.",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.0",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"blur",
|
|
7
7
|
"gaussian"
|
|
@@ -9,16 +9,26 @@
|
|
|
9
9
|
"homepage": "https://github.com/andr83/glur/issues",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"repository": "nodeca/glur",
|
|
12
|
+
"types": "./lib/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./lib/index.d.ts",
|
|
16
|
+
"default": "./lib/index.mjs"
|
|
17
|
+
},
|
|
18
|
+
"./package.json": "./package.json"
|
|
19
|
+
},
|
|
12
20
|
"files": [
|
|
13
|
-
"
|
|
14
|
-
"mono16.js"
|
|
21
|
+
"lib/"
|
|
15
22
|
],
|
|
16
23
|
"scripts": {
|
|
17
|
-
"
|
|
24
|
+
"demo": "npx serve .",
|
|
25
|
+
"lint": "eslint .",
|
|
26
|
+
"test": "npm run lint"
|
|
18
27
|
},
|
|
19
28
|
"devDependencies": {
|
|
20
29
|
"ansi": "0.3.x",
|
|
21
30
|
"benchmark": "1.0.x",
|
|
22
|
-
"eslint": "^
|
|
31
|
+
"eslint": "^9",
|
|
32
|
+
"neostandard": "^0.13.0"
|
|
23
33
|
}
|
|
24
34
|
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
1.1.2 / 2016-05-05
|
|
2
|
-
------------------
|
|
3
|
-
|
|
4
|
-
- Fixed typo in RGBA blur math equations (regression from 1.1.0),
|
|
5
|
-
thanks to @tonykwok.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
1.1.1 / 2015-11-10
|
|
9
|
-
------------------
|
|
10
|
-
|
|
11
|
-
- Fixed line buffer size for mono blur when vertical images used.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
1.1.0 / 2015-11-05
|
|
15
|
-
------------------
|
|
16
|
-
|
|
17
|
-
- Changed interpolation fn to one from Intel's whitepaper.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
1.0.1 / 2015-11-04
|
|
21
|
-
------------------
|
|
22
|
-
|
|
23
|
-
- Maintenance: general cleanup, demo improvements.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
1.0.0 / 2015-11-02
|
|
27
|
-
------------------
|
|
28
|
-
|
|
29
|
-
- First release.
|
package/index.js
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
// Calculate Gaussian blur of an image using IIR filter
|
|
2
|
-
// The method is taken from Intel's white paper and code example attached to it:
|
|
3
|
-
// https://software.intel.com/en-us/articles/iir-gaussian-blur-filter
|
|
4
|
-
// -implementation-using-intel-advanced-vector-extensions
|
|
5
|
-
|
|
6
|
-
var a0, a1, a2, a3, b1, b2, left_corner, right_corner;
|
|
7
|
-
|
|
8
|
-
function gaussCoef(sigma) {
|
|
9
|
-
if (sigma < 0.5) {
|
|
10
|
-
sigma = 0.5;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
var a = Math.exp(0.726 * 0.726) / sigma,
|
|
14
|
-
g1 = Math.exp(-a),
|
|
15
|
-
g2 = Math.exp(-2 * a),
|
|
16
|
-
k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2);
|
|
17
|
-
|
|
18
|
-
a0 = k;
|
|
19
|
-
a1 = k * (a - 1) * g1;
|
|
20
|
-
a2 = k * (a + 1) * g1;
|
|
21
|
-
a3 = -k * g2;
|
|
22
|
-
b1 = 2 * g1;
|
|
23
|
-
b2 = -g2;
|
|
24
|
-
left_corner = (a0 + a1) / (1 - b1 - b2);
|
|
25
|
-
right_corner = (a2 + a3) / (1 - b1 - b2);
|
|
26
|
-
|
|
27
|
-
// Attempt to force type to FP32.
|
|
28
|
-
return new Float32Array([ a0, a1, a2, a3, b1, b2, left_corner, right_corner ]);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function convolveRGBA(src, out, line, coeff, width, height) {
|
|
32
|
-
// takes src image and writes the blurred and transposed result into out
|
|
33
|
-
|
|
34
|
-
var rgba;
|
|
35
|
-
var prev_src_r, prev_src_g, prev_src_b, prev_src_a;
|
|
36
|
-
var curr_src_r, curr_src_g, curr_src_b, curr_src_a;
|
|
37
|
-
var curr_out_r, curr_out_g, curr_out_b, curr_out_a;
|
|
38
|
-
var prev_out_r, prev_out_g, prev_out_b, prev_out_a;
|
|
39
|
-
var prev_prev_out_r, prev_prev_out_g, prev_prev_out_b, prev_prev_out_a;
|
|
40
|
-
|
|
41
|
-
var src_index, out_index, line_index;
|
|
42
|
-
var i, j;
|
|
43
|
-
var coeff_a0, coeff_a1, coeff_b1, coeff_b2;
|
|
44
|
-
|
|
45
|
-
for (i = 0; i < height; i++) {
|
|
46
|
-
src_index = i * width;
|
|
47
|
-
out_index = i;
|
|
48
|
-
line_index = 0;
|
|
49
|
-
|
|
50
|
-
// left to right
|
|
51
|
-
rgba = src[src_index];
|
|
52
|
-
|
|
53
|
-
prev_src_r = rgba & 0xff;
|
|
54
|
-
prev_src_g = (rgba >> 8) & 0xff;
|
|
55
|
-
prev_src_b = (rgba >> 16) & 0xff;
|
|
56
|
-
prev_src_a = (rgba >> 24) & 0xff;
|
|
57
|
-
|
|
58
|
-
prev_prev_out_r = prev_src_r * coeff[6];
|
|
59
|
-
prev_prev_out_g = prev_src_g * coeff[6];
|
|
60
|
-
prev_prev_out_b = prev_src_b * coeff[6];
|
|
61
|
-
prev_prev_out_a = prev_src_a * coeff[6];
|
|
62
|
-
|
|
63
|
-
prev_out_r = prev_prev_out_r;
|
|
64
|
-
prev_out_g = prev_prev_out_g;
|
|
65
|
-
prev_out_b = prev_prev_out_b;
|
|
66
|
-
prev_out_a = prev_prev_out_a;
|
|
67
|
-
|
|
68
|
-
coeff_a0 = coeff[0];
|
|
69
|
-
coeff_a1 = coeff[1];
|
|
70
|
-
coeff_b1 = coeff[4];
|
|
71
|
-
coeff_b2 = coeff[5];
|
|
72
|
-
|
|
73
|
-
for (j = 0; j < width; j++) {
|
|
74
|
-
rgba = src[src_index];
|
|
75
|
-
curr_src_r = rgba & 0xff;
|
|
76
|
-
curr_src_g = (rgba >> 8) & 0xff;
|
|
77
|
-
curr_src_b = (rgba >> 16) & 0xff;
|
|
78
|
-
curr_src_a = (rgba >> 24) & 0xff;
|
|
79
|
-
|
|
80
|
-
curr_out_r = curr_src_r * coeff_a0 + prev_src_r * coeff_a1 + prev_out_r * coeff_b1 + prev_prev_out_r * coeff_b2;
|
|
81
|
-
curr_out_g = curr_src_g * coeff_a0 + prev_src_g * coeff_a1 + prev_out_g * coeff_b1 + prev_prev_out_g * coeff_b2;
|
|
82
|
-
curr_out_b = curr_src_b * coeff_a0 + prev_src_b * coeff_a1 + prev_out_b * coeff_b1 + prev_prev_out_b * coeff_b2;
|
|
83
|
-
curr_out_a = curr_src_a * coeff_a0 + prev_src_a * coeff_a1 + prev_out_a * coeff_b1 + prev_prev_out_a * coeff_b2;
|
|
84
|
-
|
|
85
|
-
prev_prev_out_r = prev_out_r;
|
|
86
|
-
prev_prev_out_g = prev_out_g;
|
|
87
|
-
prev_prev_out_b = prev_out_b;
|
|
88
|
-
prev_prev_out_a = prev_out_a;
|
|
89
|
-
|
|
90
|
-
prev_out_r = curr_out_r;
|
|
91
|
-
prev_out_g = curr_out_g;
|
|
92
|
-
prev_out_b = curr_out_b;
|
|
93
|
-
prev_out_a = curr_out_a;
|
|
94
|
-
|
|
95
|
-
prev_src_r = curr_src_r;
|
|
96
|
-
prev_src_g = curr_src_g;
|
|
97
|
-
prev_src_b = curr_src_b;
|
|
98
|
-
prev_src_a = curr_src_a;
|
|
99
|
-
|
|
100
|
-
line[line_index] = prev_out_r;
|
|
101
|
-
line[line_index + 1] = prev_out_g;
|
|
102
|
-
line[line_index + 2] = prev_out_b;
|
|
103
|
-
line[line_index + 3] = prev_out_a;
|
|
104
|
-
line_index += 4;
|
|
105
|
-
src_index++;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
src_index--;
|
|
109
|
-
line_index -= 4;
|
|
110
|
-
out_index += height * (width - 1);
|
|
111
|
-
|
|
112
|
-
// right to left
|
|
113
|
-
rgba = src[src_index];
|
|
114
|
-
|
|
115
|
-
prev_src_r = rgba & 0xff;
|
|
116
|
-
prev_src_g = (rgba >> 8) & 0xff;
|
|
117
|
-
prev_src_b = (rgba >> 16) & 0xff;
|
|
118
|
-
prev_src_a = (rgba >> 24) & 0xff;
|
|
119
|
-
|
|
120
|
-
prev_prev_out_r = prev_src_r * coeff[7];
|
|
121
|
-
prev_prev_out_g = prev_src_g * coeff[7];
|
|
122
|
-
prev_prev_out_b = prev_src_b * coeff[7];
|
|
123
|
-
prev_prev_out_a = prev_src_a * coeff[7];
|
|
124
|
-
|
|
125
|
-
prev_out_r = prev_prev_out_r;
|
|
126
|
-
prev_out_g = prev_prev_out_g;
|
|
127
|
-
prev_out_b = prev_prev_out_b;
|
|
128
|
-
prev_out_a = prev_prev_out_a;
|
|
129
|
-
|
|
130
|
-
curr_src_r = prev_src_r;
|
|
131
|
-
curr_src_g = prev_src_g;
|
|
132
|
-
curr_src_b = prev_src_b;
|
|
133
|
-
curr_src_a = prev_src_a;
|
|
134
|
-
|
|
135
|
-
coeff_a0 = coeff[2];
|
|
136
|
-
coeff_a1 = coeff[3];
|
|
137
|
-
|
|
138
|
-
for (j = width - 1; j >= 0; j--) {
|
|
139
|
-
curr_out_r = curr_src_r * coeff_a0 + prev_src_r * coeff_a1 + prev_out_r * coeff_b1 + prev_prev_out_r * coeff_b2;
|
|
140
|
-
curr_out_g = curr_src_g * coeff_a0 + prev_src_g * coeff_a1 + prev_out_g * coeff_b1 + prev_prev_out_g * coeff_b2;
|
|
141
|
-
curr_out_b = curr_src_b * coeff_a0 + prev_src_b * coeff_a1 + prev_out_b * coeff_b1 + prev_prev_out_b * coeff_b2;
|
|
142
|
-
curr_out_a = curr_src_a * coeff_a0 + prev_src_a * coeff_a1 + prev_out_a * coeff_b1 + prev_prev_out_a * coeff_b2;
|
|
143
|
-
|
|
144
|
-
prev_prev_out_r = prev_out_r;
|
|
145
|
-
prev_prev_out_g = prev_out_g;
|
|
146
|
-
prev_prev_out_b = prev_out_b;
|
|
147
|
-
prev_prev_out_a = prev_out_a;
|
|
148
|
-
|
|
149
|
-
prev_out_r = curr_out_r;
|
|
150
|
-
prev_out_g = curr_out_g;
|
|
151
|
-
prev_out_b = curr_out_b;
|
|
152
|
-
prev_out_a = curr_out_a;
|
|
153
|
-
|
|
154
|
-
prev_src_r = curr_src_r;
|
|
155
|
-
prev_src_g = curr_src_g;
|
|
156
|
-
prev_src_b = curr_src_b;
|
|
157
|
-
prev_src_a = curr_src_a;
|
|
158
|
-
|
|
159
|
-
rgba = src[src_index];
|
|
160
|
-
curr_src_r = rgba & 0xff;
|
|
161
|
-
curr_src_g = (rgba >> 8) & 0xff;
|
|
162
|
-
curr_src_b = (rgba >> 16) & 0xff;
|
|
163
|
-
curr_src_a = (rgba >> 24) & 0xff;
|
|
164
|
-
|
|
165
|
-
rgba = ((line[line_index] + prev_out_r) << 0) +
|
|
166
|
-
((line[line_index + 1] + prev_out_g) << 8) +
|
|
167
|
-
((line[line_index + 2] + prev_out_b) << 16) +
|
|
168
|
-
((line[line_index + 3] + prev_out_a) << 24);
|
|
169
|
-
|
|
170
|
-
out[out_index] = rgba;
|
|
171
|
-
|
|
172
|
-
src_index--;
|
|
173
|
-
line_index -= 4;
|
|
174
|
-
out_index -= height;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
function blurRGBA(src, width, height, radius) {
|
|
181
|
-
// Quick exit on zero radius
|
|
182
|
-
if (!radius) { return; }
|
|
183
|
-
|
|
184
|
-
// Unify input data type, to keep convolver calls isomorphic
|
|
185
|
-
var src32 = new Uint32Array(src.buffer);
|
|
186
|
-
|
|
187
|
-
var out = new Uint32Array(src32.length),
|
|
188
|
-
tmp_line = new Float32Array(Math.max(width, height) * 4);
|
|
189
|
-
|
|
190
|
-
var coeff = gaussCoef(radius);
|
|
191
|
-
|
|
192
|
-
convolveRGBA(src32, out, tmp_line, coeff, width, height, radius);
|
|
193
|
-
convolveRGBA(out, src32, tmp_line, coeff, height, width, radius);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
module.exports = blurRGBA;
|
package/mono16.js
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
// Calculate Gaussian blur of an image using IIR filter
|
|
2
|
-
// The method is taken from Intel's white paper and code example attached to it:
|
|
3
|
-
// https://software.intel.com/en-us/articles/iir-gaussian-blur-filter
|
|
4
|
-
// -implementation-using-intel-advanced-vector-extensions
|
|
5
|
-
|
|
6
|
-
var a0, a1, a2, a3, b1, b2, left_corner, right_corner;
|
|
7
|
-
|
|
8
|
-
function gaussCoef(sigma) {
|
|
9
|
-
if (sigma < 0.5) {
|
|
10
|
-
sigma = 0.5;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
var a = Math.exp(0.726 * 0.726) / sigma,
|
|
14
|
-
g1 = Math.exp(-a),
|
|
15
|
-
g2 = Math.exp(-2 * a),
|
|
16
|
-
k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2);
|
|
17
|
-
|
|
18
|
-
a0 = k;
|
|
19
|
-
a1 = k * (a - 1) * g1;
|
|
20
|
-
a2 = k * (a + 1) * g1;
|
|
21
|
-
a3 = -k * g2;
|
|
22
|
-
b1 = 2 * g1;
|
|
23
|
-
b2 = -g2;
|
|
24
|
-
left_corner = (a0 + a1) / (1 - b1 - b2);
|
|
25
|
-
right_corner = (a2 + a3) / (1 - b1 - b2);
|
|
26
|
-
|
|
27
|
-
// Attempt to force type to FP32.
|
|
28
|
-
return new Float32Array([ a0, a1, a2, a3, b1, b2, left_corner, right_corner ]);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function convolveMono16(src, out, line, coeff, width, height) {
|
|
32
|
-
// takes src image and writes the blurred and transposed result into out
|
|
33
|
-
|
|
34
|
-
var prev_src, curr_src, curr_out, prev_out, prev_prev_out;
|
|
35
|
-
var src_index, out_index, line_index;
|
|
36
|
-
var i, j;
|
|
37
|
-
var coeff_a0, coeff_a1, coeff_b1, coeff_b2;
|
|
38
|
-
|
|
39
|
-
for (i = 0; i < height; i++) {
|
|
40
|
-
src_index = i * width;
|
|
41
|
-
out_index = i;
|
|
42
|
-
line_index = 0;
|
|
43
|
-
|
|
44
|
-
// left to right
|
|
45
|
-
prev_src = src[src_index];
|
|
46
|
-
prev_prev_out = prev_src * coeff[6];
|
|
47
|
-
prev_out = prev_prev_out;
|
|
48
|
-
|
|
49
|
-
coeff_a0 = coeff[0];
|
|
50
|
-
coeff_a1 = coeff[1];
|
|
51
|
-
coeff_b1 = coeff[4];
|
|
52
|
-
coeff_b2 = coeff[5];
|
|
53
|
-
|
|
54
|
-
for (j = 0; j < width; j++) {
|
|
55
|
-
curr_src = src[src_index];
|
|
56
|
-
|
|
57
|
-
curr_out = curr_src * coeff_a0 +
|
|
58
|
-
prev_src * coeff_a1 +
|
|
59
|
-
prev_out * coeff_b1 +
|
|
60
|
-
prev_prev_out * coeff_b2;
|
|
61
|
-
|
|
62
|
-
prev_prev_out = prev_out;
|
|
63
|
-
prev_out = curr_out;
|
|
64
|
-
prev_src = curr_src;
|
|
65
|
-
|
|
66
|
-
line[line_index] = prev_out;
|
|
67
|
-
line_index++;
|
|
68
|
-
src_index++;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
src_index--;
|
|
72
|
-
line_index--;
|
|
73
|
-
out_index += height * (width - 1);
|
|
74
|
-
|
|
75
|
-
// right to left
|
|
76
|
-
prev_src = src[src_index];
|
|
77
|
-
prev_prev_out = prev_src * coeff[7];
|
|
78
|
-
prev_out = prev_prev_out;
|
|
79
|
-
curr_src = prev_src;
|
|
80
|
-
|
|
81
|
-
coeff_a0 = coeff[2];
|
|
82
|
-
coeff_a1 = coeff[3];
|
|
83
|
-
|
|
84
|
-
for (j = width - 1; j >= 0; j--) {
|
|
85
|
-
curr_out = curr_src * coeff_a0 +
|
|
86
|
-
prev_src * coeff_a1 +
|
|
87
|
-
prev_out * coeff_b1 +
|
|
88
|
-
prev_prev_out * coeff_b2;
|
|
89
|
-
|
|
90
|
-
prev_prev_out = prev_out;
|
|
91
|
-
prev_out = curr_out;
|
|
92
|
-
|
|
93
|
-
prev_src = curr_src;
|
|
94
|
-
curr_src = src[src_index];
|
|
95
|
-
|
|
96
|
-
out[out_index] = line[line_index] + prev_out;
|
|
97
|
-
|
|
98
|
-
src_index--;
|
|
99
|
-
line_index--;
|
|
100
|
-
out_index -= height;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
function blurMono16(src, width, height, radius) {
|
|
107
|
-
// Quick exit on zero radius
|
|
108
|
-
if (!radius) { return; }
|
|
109
|
-
|
|
110
|
-
var out = new Uint16Array(src.length),
|
|
111
|
-
tmp_line = new Float32Array(Math.max(width, height));
|
|
112
|
-
|
|
113
|
-
var coeff = gaussCoef(radius);
|
|
114
|
-
|
|
115
|
-
convolveMono16(src, out, tmp_line, coeff, width, height, radius);
|
|
116
|
-
convolveMono16(out, src, tmp_line, coeff, height, width, radius);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
module.exports = blurMono16;
|