|
| 1 | +import assert from "assert"; |
| 2 | +import {blur, blur2} from "../src/index.js"; |
| 3 | + |
| 4 | +it("blur(values, r) returns values", () => { |
| 5 | + const V = [0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0]; |
| 6 | + assert.strictEqual(blur(V, 1), V); |
| 7 | + assert.deepStrictEqual(V, [0, 0, 0, 1, 3, 6, 7, 6, 3, 1, 0, 0, 0, 0]); |
| 8 | +}); |
| 9 | + |
| 10 | +it("blur(values, r) observes the expected integer radius r", () => { |
| 11 | + assert.deepStrictEqual(blur([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0], 0.0).map(round), [0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 27.00, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000]); |
| 12 | + assert.deepStrictEqual(blur([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0], 1.0).map(round), [0.000, 0.000, 0.000, 1.000, 3.000, 6.000, 7.000, 6.000, 3.000, 1.000, 0.000, 0.000, 0.000, 0.000]); |
| 13 | + assert.deepStrictEqual(blur([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0], 2.0).map(round), [0.216, 0.648, 1.296, 2.160, 3.240, 3.888, 4.104, 3.888, 3.240, 2.160, 1.296, 0.648, 0.216, 0.000]); |
| 14 | + assert.deepStrictEqual(blur([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0], 3.0).map(round), [1.023, 1.338, 1.732, 2.204, 2.598, 2.834, 2.913, 2.834, 2.598, 2.204, 1.653, 1.181, 0.787, 0.472]); |
| 15 | +}); |
| 16 | + |
| 17 | +it("blur(values, r) observes the expected fractional radius r", () => { |
| 18 | + assert.deepStrictEqual(blur([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0], 0.5).map(round), [0.000, 0.000, 0.000, 0.422, 2.531, 6.328, 8.438, 6.328, 2.531, 0.422, 0.000, 0.000, 0.000, 0.000]); |
| 19 | + assert.deepStrictEqual(blur([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0], 1.5).map(round), [0.053, 0.316, 0.949, 2.004, 3.322, 4.430, 4.852, 4.430, 3.322, 2.004, 0.949, 0.316, 0.053, 0.000]); |
| 20 | + assert.deepStrictEqual(blur([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0], 2.5).map(round), [0.672, 1.078, 1.609, 2.234, 2.813, 3.188, 3.313, 3.188, 2.813, 2.234, 1.594, 1.031, 0.594, 0.281]); |
| 21 | + assert.deepStrictEqual(blur([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0], 3.5).map(round), [1.266, 1.503, 1.780, 2.057, 2.294, 2.452, 2.505, 2.452, 2.294, 2.030, 1.701, 1.371, 1.081, 0.844]); |
| 22 | +}); |
| 23 | + |
| 24 | +it("blur(values, r) repeats starting values before the window", () => { |
| 25 | + assert.deepStrictEqual(blur([27, 0, 0, 0, 0, 0, 0, 0], 0.0).map(round), [27.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000]); |
| 26 | + assert.deepStrictEqual(blur([27, 0, 0, 0, 0, 0, 0, 0], 1.0).map(round), [13.000, 9.000, 4.000, 1.000, 0.000, 0.000, 0.000, 0.000]); |
| 27 | + assert.deepStrictEqual(blur([27, 0, 0, 0, 0, 0, 0, 0], 2.0).map(round), [11.016, 9.072, 6.696, 4.104, 2.160, 0.864, 0.216, 0.000]); |
| 28 | + assert.deepStrictEqual(blur([27, 0, 0, 0, 0, 0, 0, 0], 3.0).map(round), [10.233, 8.974, 7.478, 5.825, 4.093, 2.676, 1.574, 0.787]); |
| 29 | +}); |
| 30 | + |
| 31 | +it("blur(values, r) approximately preserves total value", () => { |
| 32 | + assert.strictEqual(blur([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0], 0.0).reduce((p, v) => p + v), 27); |
| 33 | + assert.strictEqual(blur([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0], 0.5).reduce((p, v) => p + v), 27); |
| 34 | + assert.strictEqual(blur([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0], 1.0).reduce((p, v) => p + v), 27); |
| 35 | + assert.strictEqual(blur([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0], 1.5).reduce((p, v) => p + v), 27); |
| 36 | + assert.strictEqual(blur([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0], 2.0).reduce((p, v) => p + v), 27.000000000000004); |
| 37 | + assert.strictEqual(blur([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0], 2.5).reduce((p, v) => p + v), 26.640625); |
| 38 | + assert.strictEqual(blur([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0], 3.0).reduce((p, v) => p + v), 26.370262390670547); |
| 39 | +}); |
| 40 | + |
| 41 | +const unit = { |
| 42 | + width: 11, |
| 43 | + height: 11, |
| 44 | + data: [ |
| 45 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 46 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 47 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 48 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 49 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 50 | + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, |
| 51 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 52 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 53 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 54 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 55 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
| 56 | + ] |
| 57 | +}; |
| 58 | + |
| 59 | +it("blur2(data, r) modifies in-place", () => { |
| 60 | + const copy = copy2(unit); |
| 61 | + assert.strictEqual(blur2(copy, 1), copy); |
| 62 | +}); |
| 63 | + |
| 64 | +it("data.height is redundant for blur2", () => { |
| 65 | + const copy = copy2(unit); |
| 66 | + delete copy.height; |
| 67 | + assert.deepStrictEqual(blur2(copy, 1).data.map(round), [ |
| 68 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 69 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 70 | + 0.000, 0.000, 0.001, 0.004, 0.008, 0.010, 0.008, 0.004, 0.001, 0.000, 0.000, |
| 71 | + 0.000, 0.000, 0.004, 0.012, 0.025, 0.029, 0.025, 0.012, 0.004, 0.000, 0.000, |
| 72 | + 0.000, 0.000, 0.008, 0.025, 0.049, 0.058, 0.049, 0.025, 0.008, 0.000, 0.000, |
| 73 | + 0.000, 0.000, 0.010, 0.029, 0.058, 0.067, 0.058, 0.029, 0.010, 0.000, 0.000, |
| 74 | + 0.000, 0.000, 0.008, 0.025, 0.049, 0.058, 0.049, 0.025, 0.008, 0.000, 0.000, |
| 75 | + 0.000, 0.000, 0.004, 0.012, 0.025, 0.029, 0.025, 0.012, 0.004, 0.000, 0.000, |
| 76 | + 0.000, 0.000, 0.001, 0.004, 0.008, 0.010, 0.008, 0.004, 0.001, 0.000, 0.000, |
| 77 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 78 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 |
| 79 | + ]); |
| 80 | +}); |
| 81 | + |
| 82 | +it("blur2(data, r) observes the expected integer radius r", () => { |
| 83 | + assert.deepStrictEqual(blur2(copy2(unit), 0), unit); |
| 84 | + assert.deepStrictEqual(blur2(copy2(unit), 1).data.map(round), [ |
| 85 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 86 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 87 | + 0.000, 0.000, 0.001, 0.004, 0.008, 0.010, 0.008, 0.004, 0.001, 0.000, 0.000, |
| 88 | + 0.000, 0.000, 0.004, 0.012, 0.025, 0.029, 0.025, 0.012, 0.004, 0.000, 0.000, |
| 89 | + 0.000, 0.000, 0.008, 0.025, 0.049, 0.058, 0.049, 0.025, 0.008, 0.000, 0.000, |
| 90 | + 0.000, 0.000, 0.010, 0.029, 0.058, 0.067, 0.058, 0.029, 0.010, 0.000, 0.000, |
| 91 | + 0.000, 0.000, 0.008, 0.025, 0.049, 0.058, 0.049, 0.025, 0.008, 0.000, 0.000, |
| 92 | + 0.000, 0.000, 0.004, 0.012, 0.025, 0.029, 0.025, 0.012, 0.004, 0.000, 0.000, |
| 93 | + 0.000, 0.000, 0.001, 0.004, 0.008, 0.010, 0.008, 0.004, 0.001, 0.000, 0.000, |
| 94 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 95 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 |
| 96 | + ]); |
| 97 | + assert.deepStrictEqual(blur2(copy2(unit), 2).data.map(round), [ |
| 98 | + 0.001, 0.001, 0.002, 0.003, 0.003, 0.004, 0.003, 0.003, 0.002, 0.001, 0.001, |
| 99 | + 0.001, 0.002, 0.004, 0.006, 0.007, 0.007, 0.007, 0.006, 0.004, 0.002, 0.001, |
| 100 | + 0.002, 0.004, 0.006, 0.010, 0.012, 0.012, 0.012, 0.010, 0.006, 0.004, 0.002, |
| 101 | + 0.003, 0.006, 0.010, 0.014, 0.017, 0.018, 0.017, 0.014, 0.010, 0.006, 0.003, |
| 102 | + 0.003, 0.007, 0.012, 0.017, 0.021, 0.022, 0.021, 0.017, 0.012, 0.007, 0.003, |
| 103 | + 0.004, 0.007, 0.012, 0.018, 0.022, 0.023, 0.022, 0.018, 0.012, 0.007, 0.004, |
| 104 | + 0.003, 0.007, 0.012, 0.017, 0.021, 0.022, 0.021, 0.017, 0.012, 0.007, 0.003, |
| 105 | + 0.003, 0.006, 0.010, 0.014, 0.017, 0.018, 0.017, 0.014, 0.010, 0.006, 0.003, |
| 106 | + 0.002, 0.004, 0.006, 0.010, 0.012, 0.012, 0.012, 0.010, 0.006, 0.004, 0.002, |
| 107 | + 0.001, 0.002, 0.004, 0.006, 0.007, 0.007, 0.007, 0.006, 0.004, 0.002, 0.001, |
| 108 | + 0.001, 0.001, 0.002, 0.003, 0.003, 0.004, 0.003, 0.003, 0.002, 0.001, 0.001 |
| 109 | + ]); |
| 110 | +}); |
| 111 | + |
| 112 | +it("blur2(data, rx, 0) does horizontal blurring", () => { |
| 113 | + assert.deepStrictEqual(blur2(copy2(unit), 0, 0).data, [ |
| 114 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 115 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 116 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 117 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 118 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 119 | + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, |
| 120 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 121 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 122 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 123 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 124 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
| 125 | + ]); |
| 126 | + assert.deepStrictEqual(blur2(copy2(unit), 1, 0).data.map(round), [ |
| 127 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 128 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 129 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 130 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 131 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 132 | + 0.000, 0.000, 0.037, 0.111, 0.222, 0.259, 0.222, 0.111, 0.037, 0.000, 0.000, |
| 133 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 134 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 135 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 136 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 137 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 |
| 138 | + ]); |
| 139 | + assert.deepStrictEqual(blur2(copy2(unit), 2, 0).data.map(round), [ |
| 140 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 141 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 142 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 143 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 144 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 145 | + 0.024, 0.048, 0.080, 0.120, 0.144, 0.152, 0.144, 0.120, 0.080, 0.048, 0.024, |
| 146 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 147 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 148 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 149 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 150 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 |
| 151 | + ]); |
| 152 | +}); |
| 153 | + |
| 154 | +it("blur2(data, 0, ry) does vertical blurring", () => { |
| 155 | + assert.deepStrictEqual(blur2(copy2(unit), 0, 0).data, [ |
| 156 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 157 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 158 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 159 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 160 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 161 | + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, |
| 162 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 163 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 164 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 165 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 166 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
| 167 | + ]); |
| 168 | + assert.deepStrictEqual(blur2(copy2(unit), 0, 1).data.map(round), [ |
| 169 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 170 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 171 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.037, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 172 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.111, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 173 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.222, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 174 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.259, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 175 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.222, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 176 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.111, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 177 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.037, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 178 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 179 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 |
| 180 | + ]); |
| 181 | + assert.deepStrictEqual(blur2(copy2(unit), 0, 2).data.map(round), [ |
| 182 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.024, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 183 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.048, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 184 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.080, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 185 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.120, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 186 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.144, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 187 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.152, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 188 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.144, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 189 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.120, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 190 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.080, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 191 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.048, 0.000, 0.000, 0.000, 0.000, 0.000, |
| 192 | + 0.000, 0.000, 0.000, 0.000, 0.000, 0.024, 0.000, 0.000, 0.000, 0.000, 0.000 |
| 193 | + ]); |
| 194 | +}); |
| 195 | + |
| 196 | +function copy2({data, width, height}) { |
| 197 | + return {data: data.slice(), width, height}; |
| 198 | +} |
| 199 | + |
| 200 | +function round(x) { |
| 201 | + return Math.round(x * 1000) / 1000 || 0; |
| 202 | +} |
0 commit comments