glur 1.1.1 → 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 CHANGED
@@ -1,10 +1,9 @@
1
1
  glur
2
2
  ====
3
3
 
4
- [![Build Status](https://travis-ci.org/nodeca/glur.svg?branch=master)](https://travis-ci.org/nodeca/glur)
5
4
  [![NPM version](https://img.shields.io/npm/v/glur.svg)](https://www.npmjs.org/package/glur)
6
5
 
7
- > Fast Gaussian Blur in pure JavaScript, via IIR filer. Speed does not depend on
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 --save
17
+ npm install glur
19
18
  ```
20
19
 
21
20
 
22
21
  API
23
22
  ---
24
23
 
25
- `require('glur')(src, width, height, radius)`
24
+ ```js
25
+ import { blurRGBA, blurMono16 } from 'glur'
26
+ ```
27
+
28
+ ### blurRGBA(src, width, height, radius)
26
29
 
27
- - __src__ - typed array with image RGBA data (will be updated with blured image).
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
- `require('glur/mono16')(src, width, height, radius)` - the same as above, but
33
- input data is grayscale Uint16Array. Can be useful to calculate unsharp mask via
34
- brightness/ligthness channel.
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,6 @@
1
+ export default function blurMono16(
2
+ src: Uint16Array,
3
+ width: number,
4
+ height: number,
5
+ radius: number
6
+ ): void
@@ -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,6 @@
1
+ export default function blurRGBA(
2
+ src: Uint8ClampedArray | Uint8Array,
3
+ width: number,
4
+ height: number,
5
+ radius: number
6
+ ): void
@@ -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
@@ -0,0 +1,2 @@
1
+ export { default as blurRGBA } from './blur_rgba.js'
2
+ export { default as blurMono16 } from './blur_mono16.js'
package/lib/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ export { default as blurRGBA } from './blur_rgba.mjs'
2
+ export { default as blurMono16 } from './blur_mono16.mjs'
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": "1.1.1",
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
- "index.js",
14
- "mono16.js"
21
+ "lib/"
15
22
  ],
16
23
  "scripts": {
17
- "test": "./node_modules/.bin/eslint ."
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": "^1.8.0"
31
+ "eslint": "^9",
32
+ "neostandard": "^0.13.0"
23
33
  }
24
34
  }
package/CHANGELOG.md DELETED
@@ -1,22 +0,0 @@
1
- 1.1.1 / 2015-11-10
2
- ------------------
3
-
4
- - Fixed line buffer size for mono blur when vertical images used.
5
-
6
-
7
- 1.1.0 / 2015-11-05
8
- ------------------
9
-
10
- - Changed interpolation fn to one from Intel's whitepaper.
11
-
12
-
13
- 1.0.1 / 2015-11-04
14
- ------------------
15
-
16
- - Maintenance: general cleanup, demo improvements.
17
-
18
-
19
- 1.0.0 / 2015-11-02
20
- ------------------
21
-
22
- - 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 + curr_src_r * coeff_a1 + prev_out_r * coeff_b1 + prev_prev_out_r * coeff_b2;
140
- curr_out_g = curr_src_g * coeff_a0 + curr_src_g * coeff_a1 + prev_out_g * coeff_b1 + prev_prev_out_g * coeff_b2;
141
- curr_out_b = curr_src_b * coeff_a0 + curr_src_b * coeff_a1 + prev_out_b * coeff_b1 + prev_prev_out_b * coeff_b2;
142
- curr_out_a = curr_src_a * coeff_a0 + curr_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;