pica 9.0.1 → 10.0.1
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 +99 -52
- package/dist/pica.cjs.d.ts +70 -0
- package/dist/pica.es.d.ts +67 -0
- package/dist/pica.js +1624 -2527
- package/dist/pica.js.map +1 -0
- package/dist/pica.min.js +2 -7
- package/dist/pica.min.js.map +1 -0
- package/dist/pica.min.mjs +8 -0
- package/dist/pica.min.mjs.map +1 -0
- package/dist/pica.mjs +1642 -0
- package/dist/pica.mjs.map +1 -0
- package/dist/pica_main.js +1633 -0
- package/dist/pica_main.js.map +1 -0
- package/dist/pica_main.mjs +1627 -0
- package/dist/pica_main.mjs.map +1 -0
- package/dist/pica_worker.js +987 -0
- package/dist/pica_worker.js.map +1 -0
- package/package.json +72 -26
- package/index.js +0 -729
- package/lib/mathlib.js +0 -57
- package/lib/mm_resize/convolve.c +0 -256
- package/lib/mm_resize/convolve.js +0 -263
- package/lib/mm_resize/convolve.wasm +0 -0
- package/lib/mm_resize/convolve_wasm_base64.js +0 -5
- package/lib/mm_resize/index.js +0 -8
- package/lib/mm_resize/resize.js +0 -52
- package/lib/mm_resize/resize_filter_gen.js +0 -120
- package/lib/mm_resize/resize_filter_info.js +0 -70
- package/lib/mm_resize/resize_wasm.js +0 -113
- package/lib/mm_unsharp_mask/index.js +0 -8
- package/lib/mm_unsharp_mask/unsharp_mask.c +0 -218
- package/lib/mm_unsharp_mask/unsharp_mask.js +0 -89
- package/lib/mm_unsharp_mask/unsharp_mask.wasm +0 -0
- package/lib/mm_unsharp_mask/unsharp_mask_wasm.js +0 -55
- package/lib/mm_unsharp_mask/unsharp_mask_wasm_base64.js +0 -5
- package/lib/pool.js +0 -65
- package/lib/stepper.js +0 -61
- package/lib/tiler.js +0 -95
- package/lib/utils.js +0 -204
- package/lib/worker.js +0 -49
package/dist/pica.js
CHANGED
|
@@ -4,2548 +4,1645 @@ pica
|
|
|
4
4
|
https://github.com/nodeca/pica
|
|
5
5
|
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.use(mm_unsharp_mask);
|
|
35
|
-
this.use(mm_resize);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
MathLib.prototype = Object.create(Multimath.prototype);
|
|
39
|
-
MathLib.prototype.constructor = MathLib;
|
|
40
|
-
|
|
41
|
-
MathLib.prototype.resizeAndUnsharp = function resizeAndUnsharp(options, cache) {
|
|
42
|
-
var result = this.resize(options, cache);
|
|
43
|
-
|
|
44
|
-
if (options.unsharpAmount) {
|
|
45
|
-
this.unsharp_mask(result, options.toWidth, options.toHeight, options.unsharpAmount, options.unsharpRadius, options.unsharpThreshold);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return result;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
module.exports = MathLib;
|
|
52
|
-
|
|
53
|
-
},{"./mm_resize":4,"./mm_unsharp_mask":9,"multimath":19}],2:[function(_dereq_,module,exports){
|
|
54
|
-
// Resize convolvers, pure JS implementation
|
|
55
|
-
//
|
|
56
|
-
'use strict'; // Precision of fixed FP values
|
|
57
|
-
//var FIXED_FRAC_BITS = 14;
|
|
58
|
-
|
|
59
|
-
function clampTo8(i) {
|
|
60
|
-
return i < 0 ? 0 : i > 255 ? 255 : i;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function clampNegative(i) {
|
|
64
|
-
return i >= 0 ? i : 0;
|
|
65
|
-
} // Convolve image data in horizontal direction. Can be used for:
|
|
66
|
-
//
|
|
67
|
-
// 1. bitmap with premultiplied alpha
|
|
68
|
-
// 2. bitmap without alpha (all values 255)
|
|
69
|
-
//
|
|
70
|
-
// Notes:
|
|
71
|
-
//
|
|
72
|
-
// - output is transposed
|
|
73
|
-
// - output resolution is ~15 bits per channel(for better precision).
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
function convolveHor(src, dest, srcW, srcH, destW, filters) {
|
|
78
|
-
var r, g, b, a;
|
|
79
|
-
var filterPtr, filterShift, filterSize;
|
|
80
|
-
var srcPtr, srcY, destX, filterVal;
|
|
81
|
-
var srcOffset = 0,
|
|
82
|
-
destOffset = 0; // For each row
|
|
83
|
-
|
|
84
|
-
for (srcY = 0; srcY < srcH; srcY++) {
|
|
85
|
-
filterPtr = 0; // Apply precomputed filters to each destination row point
|
|
86
|
-
|
|
87
|
-
for (destX = 0; destX < destW; destX++) {
|
|
88
|
-
// Get the filter that determines the current output pixel.
|
|
89
|
-
filterShift = filters[filterPtr++];
|
|
90
|
-
filterSize = filters[filterPtr++];
|
|
91
|
-
srcPtr = srcOffset + filterShift * 4 | 0;
|
|
92
|
-
r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a
|
|
93
|
-
|
|
94
|
-
for (; filterSize > 0; filterSize--) {
|
|
95
|
-
filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)
|
|
96
|
-
// Big thanks to @mraleph (Vyacheslav Egorov) for the tip.
|
|
97
|
-
|
|
98
|
-
a = a + filterVal * src[srcPtr + 3] | 0;
|
|
99
|
-
b = b + filterVal * src[srcPtr + 2] | 0;
|
|
100
|
-
g = g + filterVal * src[srcPtr + 1] | 0;
|
|
101
|
-
r = r + filterVal * src[srcPtr] | 0;
|
|
102
|
-
srcPtr = srcPtr + 4 | 0;
|
|
103
|
-
} // Store 15 bits between passes for better precision
|
|
104
|
-
// Instead of shift to 14 (FIXED_FRAC_BITS), shift to 7 only
|
|
105
|
-
//
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
dest[destOffset + 3] = clampNegative(a >> 7);
|
|
109
|
-
dest[destOffset + 2] = clampNegative(b >> 7);
|
|
110
|
-
dest[destOffset + 1] = clampNegative(g >> 7);
|
|
111
|
-
dest[destOffset] = clampNegative(r >> 7);
|
|
112
|
-
destOffset = destOffset + srcH * 4 | 0;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
destOffset = (srcY + 1) * 4 | 0;
|
|
116
|
-
srcOffset = (srcY + 1) * srcW * 4 | 0;
|
|
117
|
-
}
|
|
118
|
-
} // Supplementary method for `convolveHor()`
|
|
119
|
-
//
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
function convolveVert(src, dest, srcW, srcH, destW, filters) {
|
|
123
|
-
var r, g, b, a;
|
|
124
|
-
var filterPtr, filterShift, filterSize;
|
|
125
|
-
var srcPtr, srcY, destX, filterVal;
|
|
126
|
-
var srcOffset = 0,
|
|
127
|
-
destOffset = 0; // For each row
|
|
128
|
-
|
|
129
|
-
for (srcY = 0; srcY < srcH; srcY++) {
|
|
130
|
-
filterPtr = 0; // Apply precomputed filters to each destination row point
|
|
131
|
-
|
|
132
|
-
for (destX = 0; destX < destW; destX++) {
|
|
133
|
-
// Get the filter that determines the current output pixel.
|
|
134
|
-
filterShift = filters[filterPtr++];
|
|
135
|
-
filterSize = filters[filterPtr++];
|
|
136
|
-
srcPtr = srcOffset + filterShift * 4 | 0;
|
|
137
|
-
r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a
|
|
138
|
-
|
|
139
|
-
for (; filterSize > 0; filterSize--) {
|
|
140
|
-
filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)
|
|
141
|
-
// Big thanks to @mraleph (Vyacheslav Egorov) for the tip.
|
|
142
|
-
|
|
143
|
-
a = a + filterVal * src[srcPtr + 3] | 0;
|
|
144
|
-
b = b + filterVal * src[srcPtr + 2] | 0;
|
|
145
|
-
g = g + filterVal * src[srcPtr + 1] | 0;
|
|
146
|
-
r = r + filterVal * src[srcPtr] | 0;
|
|
147
|
-
srcPtr = srcPtr + 4 | 0;
|
|
148
|
-
} // Sync with premultiplied version for exact result match
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
r >>= 7;
|
|
152
|
-
g >>= 7;
|
|
153
|
-
b >>= 7;
|
|
154
|
-
a >>= 7; // Bring this value back in range + round result.
|
|
155
|
-
//
|
|
156
|
-
|
|
157
|
-
dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14);
|
|
158
|
-
dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14);
|
|
159
|
-
dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14);
|
|
160
|
-
dest[destOffset] = clampTo8(r + (1 << 13) >> 14);
|
|
161
|
-
destOffset = destOffset + srcH * 4 | 0;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
destOffset = (srcY + 1) * 4 | 0;
|
|
165
|
-
srcOffset = (srcY + 1) * srcW * 4 | 0;
|
|
166
|
-
}
|
|
167
|
-
} // Premultiply & convolve image data in horizontal direction. Can be used for:
|
|
168
|
-
//
|
|
169
|
-
// - Any bitmap data, extracted with `.getImageData()` method (with
|
|
170
|
-
// non-premultiplied alpha)
|
|
171
|
-
//
|
|
172
|
-
// For images without alpha channel this method is slower than `convolveHor()`
|
|
173
|
-
//
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
function convolveHorWithPre(src, dest, srcW, srcH, destW, filters) {
|
|
177
|
-
var r, g, b, a, alpha;
|
|
178
|
-
var filterPtr, filterShift, filterSize;
|
|
179
|
-
var srcPtr, srcY, destX, filterVal;
|
|
180
|
-
var srcOffset = 0,
|
|
181
|
-
destOffset = 0; // For each row
|
|
182
|
-
|
|
183
|
-
for (srcY = 0; srcY < srcH; srcY++) {
|
|
184
|
-
filterPtr = 0; // Apply precomputed filters to each destination row point
|
|
185
|
-
|
|
186
|
-
for (destX = 0; destX < destW; destX++) {
|
|
187
|
-
// Get the filter that determines the current output pixel.
|
|
188
|
-
filterShift = filters[filterPtr++];
|
|
189
|
-
filterSize = filters[filterPtr++];
|
|
190
|
-
srcPtr = srcOffset + filterShift * 4 | 0;
|
|
191
|
-
r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a
|
|
192
|
-
|
|
193
|
-
for (; filterSize > 0; filterSize--) {
|
|
194
|
-
filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)
|
|
195
|
-
// Big thanks to @mraleph (Vyacheslav Egorov) for the tip.
|
|
196
|
-
|
|
197
|
-
alpha = src[srcPtr + 3];
|
|
198
|
-
a = a + filterVal * alpha | 0;
|
|
199
|
-
b = b + filterVal * src[srcPtr + 2] * alpha | 0;
|
|
200
|
-
g = g + filterVal * src[srcPtr + 1] * alpha | 0;
|
|
201
|
-
r = r + filterVal * src[srcPtr] * alpha | 0;
|
|
202
|
-
srcPtr = srcPtr + 4 | 0;
|
|
203
|
-
} // Premultiply is (* alpha / 255).
|
|
204
|
-
// Postpone division for better performance
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
b = b / 255 | 0;
|
|
208
|
-
g = g / 255 | 0;
|
|
209
|
-
r = r / 255 | 0; // Store 15 bits between passes for better precision
|
|
210
|
-
// Instead of shift to 14 (FIXED_FRAC_BITS), shift to 7 only
|
|
211
|
-
//
|
|
212
|
-
|
|
213
|
-
dest[destOffset + 3] = clampNegative(a >> 7);
|
|
214
|
-
dest[destOffset + 2] = clampNegative(b >> 7);
|
|
215
|
-
dest[destOffset + 1] = clampNegative(g >> 7);
|
|
216
|
-
dest[destOffset] = clampNegative(r >> 7);
|
|
217
|
-
destOffset = destOffset + srcH * 4 | 0;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
destOffset = (srcY + 1) * 4 | 0;
|
|
221
|
-
srcOffset = (srcY + 1) * srcW * 4 | 0;
|
|
222
|
-
}
|
|
223
|
-
} // Supplementary method for `convolveHorWithPre()`
|
|
224
|
-
//
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
function convolveVertWithPre(src, dest, srcW, srcH, destW, filters) {
|
|
228
|
-
var r, g, b, a;
|
|
229
|
-
var filterPtr, filterShift, filterSize;
|
|
230
|
-
var srcPtr, srcY, destX, filterVal;
|
|
231
|
-
var srcOffset = 0,
|
|
232
|
-
destOffset = 0; // For each row
|
|
233
|
-
|
|
234
|
-
for (srcY = 0; srcY < srcH; srcY++) {
|
|
235
|
-
filterPtr = 0; // Apply precomputed filters to each destination row point
|
|
236
|
-
|
|
237
|
-
for (destX = 0; destX < destW; destX++) {
|
|
238
|
-
// Get the filter that determines the current output pixel.
|
|
239
|
-
filterShift = filters[filterPtr++];
|
|
240
|
-
filterSize = filters[filterPtr++];
|
|
241
|
-
srcPtr = srcOffset + filterShift * 4 | 0;
|
|
242
|
-
r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a
|
|
243
|
-
|
|
244
|
-
for (; filterSize > 0; filterSize--) {
|
|
245
|
-
filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)
|
|
246
|
-
// Big thanks to @mraleph (Vyacheslav Egorov) for the tip.
|
|
247
|
-
|
|
248
|
-
a = a + filterVal * src[srcPtr + 3] | 0;
|
|
249
|
-
b = b + filterVal * src[srcPtr + 2] | 0;
|
|
250
|
-
g = g + filterVal * src[srcPtr + 1] | 0;
|
|
251
|
-
r = r + filterVal * src[srcPtr] | 0;
|
|
252
|
-
srcPtr = srcPtr + 4 | 0;
|
|
253
|
-
} // Downscale to leave room for un-premultiply
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
r >>= 7;
|
|
257
|
-
g >>= 7;
|
|
258
|
-
b >>= 7;
|
|
259
|
-
a >>= 7; // Un-premultiply
|
|
260
|
-
|
|
261
|
-
a = clampTo8(a + (1 << 13) >> 14);
|
|
262
|
-
|
|
263
|
-
if (a > 0) {
|
|
264
|
-
r = r * 255 / a | 0;
|
|
265
|
-
g = g * 255 / a | 0;
|
|
266
|
-
b = b * 255 / a | 0;
|
|
267
|
-
} // Bring this value back in range + round result.
|
|
268
|
-
// Shift value = FIXED_FRAC_BITS + 7
|
|
269
|
-
//
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
dest[destOffset + 3] = a;
|
|
273
|
-
dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14);
|
|
274
|
-
dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14);
|
|
275
|
-
dest[destOffset] = clampTo8(r + (1 << 13) >> 14);
|
|
276
|
-
destOffset = destOffset + srcH * 4 | 0;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
destOffset = (srcY + 1) * 4 | 0;
|
|
280
|
-
srcOffset = (srcY + 1) * srcW * 4 | 0;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
module.exports = {
|
|
285
|
-
convolveHor: convolveHor,
|
|
286
|
-
convolveVert: convolveVert,
|
|
287
|
-
convolveHorWithPre: convolveHorWithPre,
|
|
288
|
-
convolveVertWithPre: convolveVertWithPre
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
},{}],3:[function(_dereq_,module,exports){
|
|
292
|
-
// This is autogenerated file from math.wasm, don't edit.
|
|
293
|
-
//
|
|
294
|
-
'use strict';
|
|
295
|
-
/* eslint-disable max-len */
|
|
296
|
-
|
|
297
|
-
module.exports = 'AGFzbQEAAAAADAZkeWxpbmsAAAAAAAEYA2AGf39/f39/AGAAAGAIf39/f39/f38AAg8BA2VudgZtZW1vcnkCAAADBwYBAAAAAAIGBgF/AEEACweUAQgRX193YXNtX2NhbGxfY3RvcnMAAAtjb252b2x2ZUhvcgABDGNvbnZvbHZlVmVydAACEmNvbnZvbHZlSG9yV2l0aFByZQADE2NvbnZvbHZlVmVydFdpdGhQcmUABApjb252b2x2ZUhWAAUMX19kc29faGFuZGxlAwAYX193YXNtX2FwcGx5X2RhdGFfcmVsb2NzAAAKyA4GAwABC4wDARB/AkAgA0UNACAERQ0AIANBAnQhFQNAQQAhE0EAIQsDQCALQQJqIQcCfyALQQF0IAVqIgYuAQIiC0UEQEEAIQhBACEGQQAhCUEAIQogBwwBCyASIAYuAQBqIQhBACEJQQAhCiALIRRBACEOIAchBkEAIQ8DQCAFIAZBAXRqLgEAIhAgACAIQQJ0aigCACIRQRh2bCAPaiEPIBFB/wFxIBBsIAlqIQkgEUEQdkH/AXEgEGwgDmohDiARQQh2Qf8BcSAQbCAKaiEKIAhBAWohCCAGQQFqIQYgFEEBayIUDQALIAlBB3UhCCAKQQd1IQYgDkEHdSEJIA9BB3UhCiAHIAtqCyELIAEgDEEBdCIHaiAIQQAgCEEAShs7AQAgASAHQQJyaiAGQQAgBkEAShs7AQAgASAHQQRyaiAJQQAgCUEAShs7AQAgASAHQQZyaiAKQQAgCkEAShs7AQAgDCAVaiEMIBNBAWoiEyAERw0ACyANQQFqIg0gAmwhEiANQQJ0IQwgAyANRw0ACwsL2gMBD38CQCADRQ0AIARFDQAgAkECdCEUA0AgCyEMQQAhE0EAIQIDQCACQQJqIQYCfyACQQF0IAVqIgcuAQIiAkUEQEEAIQhBACEHQQAhCkEAIQkgBgwBCyAHLgEAQQJ0IBJqIQhBACEJIAIhCkEAIQ0gBiEHQQAhDkEAIQ8DQCAFIAdBAXRqLgEAIhAgACAIQQF0IhFqLwEAbCAJaiEJIAAgEUEGcmovAQAgEGwgDmohDiAAIBFBBHJqLwEAIBBsIA9qIQ8gACARQQJyai8BACAQbCANaiENIAhBBGohCCAHQQFqIQcgCkEBayIKDQALIAlBB3UhCCANQQd1IQcgDkEHdSEKIA9BB3UhCSACIAZqCyECIAEgDEECdGogB0GAQGtBDnUiBkH/ASAGQf8BSBsiBkEAIAZBAEobQQh0QYD+A3EgCUGAQGtBDnUiBkH/ASAGQf8BSBsiBkEAIAZBAEobQRB0QYCA/AdxIApBgEBrQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG0EYdHJyIAhBgEBrQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG3I2AgAgAyAMaiEMIBNBAWoiEyAERw0ACyAUIAtBAWoiC2whEiADIAtHDQALCwuSAwEQfwJAIANFDQAgBEUNACADQQJ0IRUDQEEAIRNBACEGA0AgBkECaiEIAn8gBkEBdCAFaiIGLgECIgdFBEBBACEJQQAhDEEAIQ1BACEOIAgMAQsgEiAGLgEAaiEJQQAhDkEAIQ1BACEMIAchFEEAIQ8gCCEGA0AgBSAGQQF0ai4BACAAIAlBAnRqKAIAIhBBGHZsIhEgD2ohDyARIBBBEHZB/wFxbCAMaiEMIBEgEEEIdkH/AXFsIA1qIQ0gESAQQf8BcWwgDmohDiAJQQFqIQkgBkEBaiEGIBRBAWsiFA0ACyAPQQd1IQkgByAIagshBiABIApBAXQiCGogDkH/AW1BB3UiB0EAIAdBAEobOwEAIAEgCEECcmogDUH/AW1BB3UiB0EAIAdBAEobOwEAIAEgCEEEcmogDEH/AW1BB3UiB0EAIAdBAEobOwEAIAEgCEEGcmogCUEAIAlBAEobOwEAIAogFWohCiATQQFqIhMgBEcNAAsgC0EBaiILIAJsIRIgC0ECdCEKIAMgC0cNAAsLC4IEAQ9/AkAgA0UNACAERQ0AIAJBAnQhFANAIAshDEEAIRJBACEHA0AgB0ECaiEKAn8gB0EBdCAFaiICLgECIhNFBEBBACEIQQAhCUEAIQYgCiEHQQAMAQsgAi4BAEECdCARaiEJQQAhByATIQJBACENIAohBkEAIQ5BACEPA0AgBSAGQQF0ai4BACIIIAAgCUEBdCIQai8BAGwgB2ohByAAIBBBBnJqLwEAIAhsIA5qIQ4gACAQQQRyai8BACAIbCAPaiEPIAAgEEECcmovAQAgCGwgDWohDSAJQQRqIQkgBkEBaiEGIAJBAWsiAg0ACyAHQQd1IQggDUEHdSEJIA9BB3UhBiAKIBNqIQcgDkEHdQtBgEBrQQ51IgJB/wEgAkH/AUgbIgJBACACQQBKGyIKQf8BcQRAIAlB/wFsIAJtIQkgCEH/AWwgAm0hCCAGQf8BbCACbSEGCyABIAxBAnRqIAlBgEBrQQ51IgJB/wEgAkH/AUgbIgJBACACQQBKG0EIdEGA/gNxIAZBgEBrQQ51IgJB/wEgAkH/AUgbIgJBACACQQBKG0EQdEGAgPwHcSAKQRh0ciAIQYBAa0EOdSICQf8BIAJB/wFIGyICQQAgAkEAShtycjYCACADIAxqIQwgEkEBaiISIARHDQALIBQgC0EBaiILbCERIAMgC0cNAAsLC0AAIAcEQEEAIAIgAyAEIAUgABADIAJBACAEIAUgBiABEAQPC0EAIAIgAyAEIAUgABABIAJBACAEIAUgBiABEAIL';
|
|
298
|
-
|
|
299
|
-
},{}],4:[function(_dereq_,module,exports){
|
|
300
|
-
'use strict';
|
|
301
|
-
|
|
302
|
-
module.exports = {
|
|
303
|
-
name: 'resize',
|
|
304
|
-
fn: _dereq_('./resize'),
|
|
305
|
-
wasm_fn: _dereq_('./resize_wasm'),
|
|
306
|
-
wasm_src: _dereq_('./convolve_wasm_base64')
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
},{"./convolve_wasm_base64":3,"./resize":5,"./resize_wasm":8}],5:[function(_dereq_,module,exports){
|
|
310
|
-
'use strict';
|
|
311
|
-
|
|
312
|
-
var createFilters = _dereq_('./resize_filter_gen');
|
|
313
|
-
|
|
314
|
-
var _require = _dereq_('./convolve'),
|
|
315
|
-
convolveHor = _require.convolveHor,
|
|
316
|
-
convolveVert = _require.convolveVert,
|
|
317
|
-
convolveHorWithPre = _require.convolveHorWithPre,
|
|
318
|
-
convolveVertWithPre = _require.convolveVertWithPre;
|
|
319
|
-
|
|
320
|
-
function hasAlpha(src, width, height) {
|
|
321
|
-
var ptr = 3,
|
|
322
|
-
len = width * height * 4 | 0;
|
|
323
|
-
|
|
324
|
-
while (ptr < len) {
|
|
325
|
-
if (src[ptr] !== 255) return true;
|
|
326
|
-
ptr = ptr + 4 | 0;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
return false;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
function resetAlpha(dst, width, height) {
|
|
333
|
-
var ptr = 3,
|
|
334
|
-
len = width * height * 4 | 0;
|
|
335
|
-
|
|
336
|
-
while (ptr < len) {
|
|
337
|
-
dst[ptr] = 0xFF;
|
|
338
|
-
ptr = ptr + 4 | 0;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
module.exports = function resize(options) {
|
|
343
|
-
var src = options.src;
|
|
344
|
-
var srcW = options.width;
|
|
345
|
-
var srcH = options.height;
|
|
346
|
-
var destW = options.toWidth;
|
|
347
|
-
var destH = options.toHeight;
|
|
348
|
-
var scaleX = options.scaleX || options.toWidth / options.width;
|
|
349
|
-
var scaleY = options.scaleY || options.toHeight / options.height;
|
|
350
|
-
var offsetX = options.offsetX || 0;
|
|
351
|
-
var offsetY = options.offsetY || 0;
|
|
352
|
-
var dest = options.dest || new Uint8Array(destW * destH * 4);
|
|
353
|
-
var filter = typeof options.filter === 'undefined' ? 'mks2013' : options.filter;
|
|
354
|
-
var filtersX = createFilters(filter, srcW, destW, scaleX, offsetX),
|
|
355
|
-
filtersY = createFilters(filter, srcH, destH, scaleY, offsetY);
|
|
356
|
-
var tmp = new Uint16Array(destW * srcH * 4); // Autodetect if alpha channel exists, and use appropriate method
|
|
357
|
-
|
|
358
|
-
if (hasAlpha(src, srcW, srcH)) {
|
|
359
|
-
convolveHorWithPre(src, tmp, srcW, srcH, destW, filtersX);
|
|
360
|
-
convolveVertWithPre(tmp, dest, srcH, destW, destH, filtersY);
|
|
361
|
-
} else {
|
|
362
|
-
convolveHor(src, tmp, srcW, srcH, destW, filtersX);
|
|
363
|
-
convolveVert(tmp, dest, srcH, destW, destH, filtersY);
|
|
364
|
-
resetAlpha(dest, destW, destH);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
return dest;
|
|
368
|
-
};
|
|
369
|
-
|
|
370
|
-
},{"./convolve":2,"./resize_filter_gen":6}],6:[function(_dereq_,module,exports){
|
|
371
|
-
// Calculate convolution filters for each destination point,
|
|
372
|
-
// and pack data to Int16Array:
|
|
373
|
-
//
|
|
374
|
-
// [ shift, length, data..., shift2, length2, data..., ... ]
|
|
375
|
-
//
|
|
376
|
-
// - shift - offset in src image
|
|
377
|
-
// - length - filter length (in src points)
|
|
378
|
-
// - data - filter values sequence
|
|
379
|
-
//
|
|
380
|
-
'use strict';
|
|
381
|
-
|
|
382
|
-
var FILTER_INFO = _dereq_('./resize_filter_info'); // Precision of fixed FP values
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
var FIXED_FRAC_BITS = 14;
|
|
386
|
-
|
|
387
|
-
function toFixedPoint(num) {
|
|
388
|
-
return Math.round(num * ((1 << FIXED_FRAC_BITS) - 1));
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
module.exports = function resizeFilterGen(filter, srcSize, destSize, scale, offset) {
|
|
392
|
-
var filterFunction = FILTER_INFO.filter[filter].fn;
|
|
393
|
-
var scaleInverted = 1.0 / scale;
|
|
394
|
-
var scaleClamped = Math.min(1.0, scale); // For upscale
|
|
395
|
-
// Filter window (averaging interval), scaled to src image
|
|
396
|
-
|
|
397
|
-
var srcWindow = FILTER_INFO.filter[filter].win / scaleClamped;
|
|
398
|
-
var destPixel, srcPixel, srcFirst, srcLast, filterElementSize, floatFilter, fxpFilter, total, pxl, idx, floatVal, filterTotal, filterVal;
|
|
399
|
-
var leftNotEmpty, rightNotEmpty, filterShift, filterSize;
|
|
400
|
-
var maxFilterElementSize = Math.floor((srcWindow + 1) * 2);
|
|
401
|
-
var packedFilter = new Int16Array((maxFilterElementSize + 2) * destSize);
|
|
402
|
-
var packedFilterPtr = 0;
|
|
403
|
-
var slowCopy = !packedFilter.subarray || !packedFilter.set; // For each destination pixel calculate source range and built filter values
|
|
404
|
-
|
|
405
|
-
for (destPixel = 0; destPixel < destSize; destPixel++) {
|
|
406
|
-
// Scaling should be done relative to central pixel point
|
|
407
|
-
srcPixel = (destPixel + 0.5) * scaleInverted + offset;
|
|
408
|
-
srcFirst = Math.max(0, Math.floor(srcPixel - srcWindow));
|
|
409
|
-
srcLast = Math.min(srcSize - 1, Math.ceil(srcPixel + srcWindow));
|
|
410
|
-
filterElementSize = srcLast - srcFirst + 1;
|
|
411
|
-
floatFilter = new Float32Array(filterElementSize);
|
|
412
|
-
fxpFilter = new Int16Array(filterElementSize);
|
|
413
|
-
total = 0.0; // Fill filter values for calculated range
|
|
414
|
-
|
|
415
|
-
for (pxl = srcFirst, idx = 0; pxl <= srcLast; pxl++, idx++) {
|
|
416
|
-
floatVal = filterFunction((pxl + 0.5 - srcPixel) * scaleClamped);
|
|
417
|
-
total += floatVal;
|
|
418
|
-
floatFilter[idx] = floatVal;
|
|
419
|
-
} // Normalize filter, convert to fixed point and accumulate conversion error
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
filterTotal = 0;
|
|
423
|
-
|
|
424
|
-
for (idx = 0; idx < floatFilter.length; idx++) {
|
|
425
|
-
filterVal = floatFilter[idx] / total;
|
|
426
|
-
filterTotal += filterVal;
|
|
427
|
-
fxpFilter[idx] = toFixedPoint(filterVal);
|
|
428
|
-
} // Compensate normalization error, to minimize brightness drift
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
fxpFilter[destSize >> 1] += toFixedPoint(1.0 - filterTotal); //
|
|
432
|
-
// Now pack filter to useable form
|
|
433
|
-
//
|
|
434
|
-
// 1. Trim heading and tailing zero values, and compensate shitf/length
|
|
435
|
-
// 2. Put all to single array in this format:
|
|
436
|
-
//
|
|
437
|
-
// [ pos shift, data length, value1, value2, value3, ... ]
|
|
438
|
-
//
|
|
439
|
-
|
|
440
|
-
leftNotEmpty = 0;
|
|
441
|
-
|
|
442
|
-
while (leftNotEmpty < fxpFilter.length && fxpFilter[leftNotEmpty] === 0) {
|
|
443
|
-
leftNotEmpty++;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
if (leftNotEmpty < fxpFilter.length) {
|
|
447
|
-
rightNotEmpty = fxpFilter.length - 1;
|
|
448
|
-
|
|
449
|
-
while (rightNotEmpty > 0 && fxpFilter[rightNotEmpty] === 0) {
|
|
450
|
-
rightNotEmpty--;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
filterShift = srcFirst + leftNotEmpty;
|
|
454
|
-
filterSize = rightNotEmpty - leftNotEmpty + 1;
|
|
455
|
-
packedFilter[packedFilterPtr++] = filterShift; // shift
|
|
456
|
-
|
|
457
|
-
packedFilter[packedFilterPtr++] = filterSize; // size
|
|
458
|
-
|
|
459
|
-
if (!slowCopy) {
|
|
460
|
-
packedFilter.set(fxpFilter.subarray(leftNotEmpty, rightNotEmpty + 1), packedFilterPtr);
|
|
461
|
-
packedFilterPtr += filterSize;
|
|
462
|
-
} else {
|
|
463
|
-
// fallback for old IE < 11, without subarray/set methods
|
|
464
|
-
for (idx = leftNotEmpty; idx <= rightNotEmpty; idx++) {
|
|
465
|
-
packedFilter[packedFilterPtr++] = fxpFilter[idx];
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
} else {
|
|
469
|
-
// zero data, write header only
|
|
470
|
-
packedFilter[packedFilterPtr++] = 0; // shift
|
|
471
|
-
|
|
472
|
-
packedFilter[packedFilterPtr++] = 0; // size
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
return packedFilter;
|
|
477
|
-
};
|
|
478
|
-
|
|
479
|
-
},{"./resize_filter_info":7}],7:[function(_dereq_,module,exports){
|
|
480
|
-
// Filter definitions to build tables for
|
|
481
|
-
// resizing convolvers.
|
|
482
|
-
//
|
|
483
|
-
// Presets for quality 0..3. Filter functions + window size
|
|
484
|
-
//
|
|
485
|
-
'use strict';
|
|
486
|
-
|
|
487
|
-
var filter = {
|
|
488
|
-
// Nearest neibor
|
|
489
|
-
box: {
|
|
490
|
-
win: 0.5,
|
|
491
|
-
fn: function fn(x) {
|
|
492
|
-
if (x < 0) x = -x;
|
|
493
|
-
return x < 0.5 ? 1.0 : 0.0;
|
|
494
|
-
}
|
|
495
|
-
},
|
|
496
|
-
// // Hamming
|
|
497
|
-
hamming: {
|
|
498
|
-
win: 1.0,
|
|
499
|
-
fn: function fn(x) {
|
|
500
|
-
if (x < 0) x = -x;
|
|
501
|
-
|
|
502
|
-
if (x >= 1.0) {
|
|
503
|
-
return 0.0;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
if (x < 1.19209290E-07) {
|
|
507
|
-
return 1.0;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
var xpi = x * Math.PI;
|
|
511
|
-
return Math.sin(xpi) / xpi * (0.54 + 0.46 * Math.cos(xpi / 1.0));
|
|
512
|
-
}
|
|
513
|
-
},
|
|
514
|
-
// Lanczos, win = 2
|
|
515
|
-
lanczos2: {
|
|
516
|
-
win: 2.0,
|
|
517
|
-
fn: function fn(x) {
|
|
518
|
-
if (x < 0) x = -x;
|
|
519
|
-
|
|
520
|
-
if (x >= 2.0) {
|
|
521
|
-
return 0.0;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
if (x < 1.19209290E-07) {
|
|
525
|
-
return 1.0;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
var xpi = x * Math.PI;
|
|
529
|
-
return Math.sin(xpi) / xpi * Math.sin(xpi / 2.0) / (xpi / 2.0);
|
|
530
|
-
}
|
|
531
|
-
},
|
|
532
|
-
// Lanczos, win = 3
|
|
533
|
-
lanczos3: {
|
|
534
|
-
win: 3.0,
|
|
535
|
-
fn: function fn(x) {
|
|
536
|
-
if (x < 0) x = -x;
|
|
537
|
-
|
|
538
|
-
if (x >= 3.0) {
|
|
539
|
-
return 0.0;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
if (x < 1.19209290E-07) {
|
|
543
|
-
return 1.0;
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
var xpi = x * Math.PI;
|
|
547
|
-
return Math.sin(xpi) / xpi * Math.sin(xpi / 3.0) / (xpi / 3.0);
|
|
548
|
-
}
|
|
549
|
-
},
|
|
550
|
-
// Magic Kernel Sharp 2013, win = 2.5
|
|
551
|
-
// http://johncostella.com/magic/
|
|
552
|
-
mks2013: {
|
|
553
|
-
win: 2.5,
|
|
554
|
-
fn: function fn(x) {
|
|
555
|
-
if (x < 0) x = -x;
|
|
556
|
-
|
|
557
|
-
if (x >= 2.5) {
|
|
558
|
-
return 0.0;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
if (x >= 1.5) {
|
|
562
|
-
return -0.125 * (x - 2.5) * (x - 2.5);
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
if (x >= 0.5) {
|
|
566
|
-
return 0.25 * (4 * x * x - 11 * x + 7);
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
return 1.0625 - 1.75 * x * x;
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
};
|
|
573
|
-
module.exports = {
|
|
574
|
-
filter: filter,
|
|
575
|
-
// Legacy mapping
|
|
576
|
-
f2q: {
|
|
577
|
-
box: 0,
|
|
578
|
-
hamming: 1,
|
|
579
|
-
lanczos2: 2,
|
|
580
|
-
lanczos3: 3
|
|
581
|
-
},
|
|
582
|
-
q2f: ['box', 'hamming', 'lanczos2', 'lanczos3']
|
|
583
|
-
};
|
|
584
|
-
|
|
585
|
-
},{}],8:[function(_dereq_,module,exports){
|
|
586
|
-
'use strict';
|
|
587
|
-
|
|
588
|
-
var createFilters = _dereq_('./resize_filter_gen');
|
|
589
|
-
|
|
590
|
-
function hasAlpha(src, width, height) {
|
|
591
|
-
var ptr = 3,
|
|
592
|
-
len = width * height * 4 | 0;
|
|
593
|
-
|
|
594
|
-
while (ptr < len) {
|
|
595
|
-
if (src[ptr] !== 255) return true;
|
|
596
|
-
ptr = ptr + 4 | 0;
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
return false;
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
function resetAlpha(dst, width, height) {
|
|
603
|
-
var ptr = 3,
|
|
604
|
-
len = width * height * 4 | 0;
|
|
605
|
-
|
|
606
|
-
while (ptr < len) {
|
|
607
|
-
dst[ptr] = 0xFF;
|
|
608
|
-
ptr = ptr + 4 | 0;
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
function asUint8Array(src) {
|
|
613
|
-
return new Uint8Array(src.buffer, 0, src.byteLength);
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
var IS_LE = true; // should not crash everything on module load in old browsers
|
|
617
|
-
|
|
618
|
-
try {
|
|
619
|
-
IS_LE = new Uint32Array(new Uint8Array([1, 0, 0, 0]).buffer)[0] === 1;
|
|
620
|
-
} catch (__) {}
|
|
621
|
-
|
|
622
|
-
function copyInt16asLE(src, target, target_offset) {
|
|
623
|
-
if (IS_LE) {
|
|
624
|
-
target.set(asUint8Array(src), target_offset);
|
|
625
|
-
return;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
for (var ptr = target_offset, i = 0; i < src.length; i++) {
|
|
629
|
-
var data = src[i];
|
|
630
|
-
target[ptr++] = data & 0xFF;
|
|
631
|
-
target[ptr++] = data >> 8 & 0xFF;
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
module.exports = function resize_wasm(options) {
|
|
636
|
-
var src = options.src;
|
|
637
|
-
var srcW = options.width;
|
|
638
|
-
var srcH = options.height;
|
|
639
|
-
var destW = options.toWidth;
|
|
640
|
-
var destH = options.toHeight;
|
|
641
|
-
var scaleX = options.scaleX || options.toWidth / options.width;
|
|
642
|
-
var scaleY = options.scaleY || options.toHeight / options.height;
|
|
643
|
-
var offsetX = options.offsetX || 0.0;
|
|
644
|
-
var offsetY = options.offsetY || 0.0;
|
|
645
|
-
var dest = options.dest || new Uint8Array(destW * destH * 4);
|
|
646
|
-
var filter = typeof options.filter === 'undefined' ? 'mks2013' : options.filter;
|
|
647
|
-
var filtersX = createFilters(filter, srcW, destW, scaleX, offsetX),
|
|
648
|
-
filtersY = createFilters(filter, srcH, destH, scaleY, offsetY); // destination is 0 too.
|
|
649
|
-
|
|
650
|
-
var src_offset = 0;
|
|
651
|
-
var src_size = Math.max(src.byteLength, dest.byteLength); // buffer between convolve passes
|
|
652
|
-
|
|
653
|
-
var tmp_offset = this.__align(src_offset + src_size);
|
|
654
|
-
|
|
655
|
-
var tmp_size = srcH * destW * 4 * 2; // 2 bytes per channel
|
|
656
|
-
|
|
657
|
-
var filtersX_offset = this.__align(tmp_offset + tmp_size);
|
|
658
|
-
|
|
659
|
-
var filtersY_offset = this.__align(filtersX_offset + filtersX.byteLength);
|
|
660
|
-
|
|
661
|
-
var alloc_bytes = filtersY_offset + filtersY.byteLength;
|
|
662
|
-
|
|
663
|
-
var instance = this.__instance('resize', alloc_bytes); //
|
|
664
|
-
// Fill memory block with data to process
|
|
665
|
-
//
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
var mem = new Uint8Array(this.__memory.buffer);
|
|
669
|
-
var mem32 = new Uint32Array(this.__memory.buffer); // 32-bit copy is much faster in chrome
|
|
670
|
-
|
|
671
|
-
var src32 = new Uint32Array(src.buffer);
|
|
672
|
-
mem32.set(src32); // We should guarantee LE bytes order. Filters are not big, so
|
|
673
|
-
// speed difference is not significant vs direct .set()
|
|
674
|
-
|
|
675
|
-
copyInt16asLE(filtersX, mem, filtersX_offset);
|
|
676
|
-
copyInt16asLE(filtersY, mem, filtersY_offset); // Now call webassembly method
|
|
677
|
-
// emsdk does method names with '_'
|
|
678
|
-
|
|
679
|
-
var fn = instance.exports.convolveHV || instance.exports._convolveHV;
|
|
680
|
-
|
|
681
|
-
if (hasAlpha(src, srcW, srcH)) {
|
|
682
|
-
fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH, 1);
|
|
683
|
-
} else {
|
|
684
|
-
fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH, 0);
|
|
685
|
-
resetAlpha(dest, destW, destH);
|
|
686
|
-
} //
|
|
687
|
-
// Copy data back to typed array
|
|
688
|
-
//
|
|
689
|
-
// 32-bit copy is much faster in chrome
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
var dest32 = new Uint32Array(dest.buffer);
|
|
693
|
-
dest32.set(new Uint32Array(this.__memory.buffer, 0, destH * destW));
|
|
694
|
-
return dest;
|
|
695
|
-
};
|
|
696
|
-
|
|
697
|
-
},{"./resize_filter_gen":6}],9:[function(_dereq_,module,exports){
|
|
698
|
-
'use strict';
|
|
699
|
-
|
|
700
|
-
module.exports = {
|
|
701
|
-
name: 'unsharp_mask',
|
|
702
|
-
fn: _dereq_('./unsharp_mask'),
|
|
703
|
-
wasm_fn: _dereq_('./unsharp_mask_wasm'),
|
|
704
|
-
wasm_src: _dereq_('./unsharp_mask_wasm_base64')
|
|
705
|
-
};
|
|
706
|
-
|
|
707
|
-
},{"./unsharp_mask":10,"./unsharp_mask_wasm":11,"./unsharp_mask_wasm_base64":12}],10:[function(_dereq_,module,exports){
|
|
708
|
-
// Unsharp mask filter
|
|
709
|
-
//
|
|
710
|
-
// http://stackoverflow.com/a/23322820/1031804
|
|
711
|
-
// USM(O) = O + (2 * (Amount / 100) * (O - GB))
|
|
712
|
-
// GB - gaussian blur.
|
|
713
|
-
//
|
|
714
|
-
// Image is converted from RGB to HSV, unsharp mask is applied to the
|
|
715
|
-
// brightness channel and then image is converted back to RGB.
|
|
716
|
-
//
|
|
717
|
-
'use strict';
|
|
718
|
-
|
|
719
|
-
var glur_mono16 = _dereq_('glur/mono16');
|
|
720
|
-
|
|
721
|
-
function hsv_v16(img, width, height) {
|
|
722
|
-
var size = width * height;
|
|
723
|
-
var out = new Uint16Array(size);
|
|
724
|
-
var r, g, b, max;
|
|
725
|
-
|
|
726
|
-
for (var i = 0; i < size; i++) {
|
|
727
|
-
r = img[4 * i];
|
|
728
|
-
g = img[4 * i + 1];
|
|
729
|
-
b = img[4 * i + 2];
|
|
730
|
-
max = r >= g && r >= b ? r : g >= b && g >= r ? g : b;
|
|
731
|
-
out[i] = max << 8;
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
return out;
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
module.exports = function unsharp(img, width, height, amount, radius, threshold) {
|
|
738
|
-
var v1, v2, vmul;
|
|
739
|
-
var diff, iTimes4;
|
|
740
|
-
|
|
741
|
-
if (amount === 0 || radius < 0.5) {
|
|
742
|
-
return;
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
if (radius > 2.0) {
|
|
746
|
-
radius = 2.0;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
var brightness = hsv_v16(img, width, height);
|
|
750
|
-
var blured = new Uint16Array(brightness); // copy, because blur modify src
|
|
751
|
-
|
|
752
|
-
glur_mono16(blured, width, height, radius);
|
|
753
|
-
var amountFp = amount / 100 * 0x1000 + 0.5 | 0;
|
|
754
|
-
var thresholdFp = threshold << 8;
|
|
755
|
-
var size = width * height;
|
|
756
|
-
/* eslint-disable indent */
|
|
757
|
-
|
|
758
|
-
for (var i = 0; i < size; i++) {
|
|
759
|
-
v1 = brightness[i];
|
|
760
|
-
diff = v1 - blured[i];
|
|
761
|
-
|
|
762
|
-
if (Math.abs(diff) >= thresholdFp) {
|
|
763
|
-
// add unsharp mask to the brightness channel
|
|
764
|
-
v2 = v1 + (amountFp * diff + 0x800 >> 12); // Both v1 and v2 are within [0.0 .. 255.0] (0000-FF00) range, never going into
|
|
765
|
-
// [255.003 .. 255.996] (FF01-FFFF). This allows to round this value as (x+.5)|0
|
|
766
|
-
// later without overflowing.
|
|
767
|
-
|
|
768
|
-
v2 = v2 > 0xff00 ? 0xff00 : v2;
|
|
769
|
-
v2 = v2 < 0x0000 ? 0x0000 : v2; // Avoid division by 0. V=0 means rgb(0,0,0), unsharp with unsharpAmount>0 cannot
|
|
770
|
-
// change this value (because diff between colors gets inflated), so no need to verify correctness.
|
|
771
|
-
|
|
772
|
-
v1 = v1 !== 0 ? v1 : 1; // Multiplying V in HSV model by a constant is equivalent to multiplying each component
|
|
773
|
-
// in RGB by the same constant (same for HSL), see also:
|
|
774
|
-
// https://beesbuzz.biz/code/16-hsv-color-transforms
|
|
775
|
-
|
|
776
|
-
vmul = (v2 << 12) / v1 | 0; // Result will be in [0..255] range because:
|
|
777
|
-
// - all numbers are positive
|
|
778
|
-
// - r,g,b <= (v1/256)
|
|
779
|
-
// - r,g,b,(v1/256),(v2/256) <= 255
|
|
780
|
-
// So highest this number can get is X*255/X+0.5=255.5 which is < 256 and rounds down.
|
|
781
|
-
|
|
782
|
-
iTimes4 = i * 4;
|
|
783
|
-
img[iTimes4] = img[iTimes4] * vmul + 0x800 >> 12; // R
|
|
784
|
-
|
|
785
|
-
img[iTimes4 + 1] = img[iTimes4 + 1] * vmul + 0x800 >> 12; // G
|
|
786
|
-
|
|
787
|
-
img[iTimes4 + 2] = img[iTimes4 + 2] * vmul + 0x800 >> 12; // B
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
|
-
};
|
|
791
|
-
|
|
792
|
-
},{"glur/mono16":18}],11:[function(_dereq_,module,exports){
|
|
793
|
-
'use strict';
|
|
794
|
-
|
|
795
|
-
module.exports = function unsharp(img, width, height, amount, radius, threshold) {
|
|
796
|
-
if (amount === 0 || radius < 0.5) {
|
|
797
|
-
return;
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
if (radius > 2.0) {
|
|
801
|
-
radius = 2.0;
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
var pixels = width * height;
|
|
805
|
-
var img_bytes_cnt = pixels * 4;
|
|
806
|
-
var hsv_bytes_cnt = pixels * 2;
|
|
807
|
-
var blur_bytes_cnt = pixels * 2;
|
|
808
|
-
var blur_line_byte_cnt = Math.max(width, height) * 4; // float32 array
|
|
809
|
-
|
|
810
|
-
var blur_coeffs_byte_cnt = 8 * 4; // float32 array
|
|
811
|
-
|
|
812
|
-
var img_offset = 0;
|
|
813
|
-
var hsv_offset = img_bytes_cnt;
|
|
814
|
-
var blur_offset = hsv_offset + hsv_bytes_cnt;
|
|
815
|
-
var blur_tmp_offset = blur_offset + blur_bytes_cnt;
|
|
816
|
-
var blur_line_offset = blur_tmp_offset + blur_bytes_cnt;
|
|
817
|
-
var blur_coeffs_offset = blur_line_offset + blur_line_byte_cnt;
|
|
818
|
-
|
|
819
|
-
var instance = this.__instance('unsharp_mask', img_bytes_cnt + hsv_bytes_cnt + blur_bytes_cnt * 2 + blur_line_byte_cnt + blur_coeffs_byte_cnt, {
|
|
820
|
-
exp: Math.exp
|
|
821
|
-
}); // 32-bit copy is much faster in chrome
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
var img32 = new Uint32Array(img.buffer);
|
|
825
|
-
var mem32 = new Uint32Array(this.__memory.buffer);
|
|
826
|
-
mem32.set(img32); // HSL
|
|
827
|
-
|
|
828
|
-
var fn = instance.exports.hsv_v16 || instance.exports._hsv_v16;
|
|
829
|
-
fn(img_offset, hsv_offset, width, height); // BLUR
|
|
830
|
-
|
|
831
|
-
fn = instance.exports.blurMono16 || instance.exports._blurMono16;
|
|
832
|
-
fn(hsv_offset, blur_offset, blur_tmp_offset, blur_line_offset, blur_coeffs_offset, width, height, radius); // UNSHARP
|
|
833
|
-
|
|
834
|
-
fn = instance.exports.unsharp || instance.exports._unsharp;
|
|
835
|
-
fn(img_offset, img_offset, hsv_offset, blur_offset, width, height, amount, threshold); // 32-bit copy is much faster in chrome
|
|
836
|
-
|
|
837
|
-
img32.set(new Uint32Array(this.__memory.buffer, 0, pixels));
|
|
838
|
-
};
|
|
839
|
-
|
|
840
|
-
},{}],12:[function(_dereq_,module,exports){
|
|
841
|
-
// This is autogenerated file from math.wasm, don't edit.
|
|
842
|
-
//
|
|
843
|
-
'use strict';
|
|
844
|
-
/* eslint-disable max-len */
|
|
845
|
-
|
|
846
|
-
module.exports = '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';
|
|
847
|
-
|
|
848
|
-
},{}],13:[function(_dereq_,module,exports){
|
|
849
|
-
'use strict';
|
|
850
|
-
|
|
851
|
-
var GC_INTERVAL = 100;
|
|
852
|
-
|
|
853
|
-
function Pool(create, idle) {
|
|
854
|
-
this.create = create;
|
|
855
|
-
this.available = [];
|
|
856
|
-
this.acquired = {};
|
|
857
|
-
this.lastId = 1;
|
|
858
|
-
this.timeoutId = 0;
|
|
859
|
-
this.idle = idle || 2000;
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
Pool.prototype.acquire = function () {
|
|
863
|
-
var _this = this;
|
|
864
|
-
|
|
865
|
-
var resource;
|
|
866
|
-
|
|
867
|
-
if (this.available.length !== 0) {
|
|
868
|
-
resource = this.available.pop();
|
|
869
|
-
} else {
|
|
870
|
-
resource = this.create();
|
|
871
|
-
resource.id = this.lastId++;
|
|
872
|
-
|
|
873
|
-
resource.release = function () {
|
|
874
|
-
return _this.release(resource);
|
|
875
|
-
};
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
this.acquired[resource.id] = resource;
|
|
879
|
-
return resource;
|
|
880
|
-
};
|
|
881
|
-
|
|
882
|
-
Pool.prototype.release = function (resource) {
|
|
883
|
-
var _this2 = this;
|
|
884
|
-
|
|
885
|
-
delete this.acquired[resource.id];
|
|
886
|
-
resource.lastUsed = Date.now();
|
|
887
|
-
this.available.push(resource);
|
|
888
|
-
|
|
889
|
-
if (this.timeoutId === 0) {
|
|
890
|
-
this.timeoutId = setTimeout(function () {
|
|
891
|
-
return _this2.gc();
|
|
892
|
-
}, GC_INTERVAL);
|
|
893
|
-
}
|
|
894
|
-
};
|
|
895
|
-
|
|
896
|
-
Pool.prototype.gc = function () {
|
|
897
|
-
var _this3 = this;
|
|
898
|
-
|
|
899
|
-
var now = Date.now();
|
|
900
|
-
this.available = this.available.filter(function (resource) {
|
|
901
|
-
if (now - resource.lastUsed > _this3.idle) {
|
|
902
|
-
resource.destroy();
|
|
903
|
-
return false;
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
return true;
|
|
907
|
-
});
|
|
908
|
-
|
|
909
|
-
if (this.available.length !== 0) {
|
|
910
|
-
this.timeoutId = setTimeout(function () {
|
|
911
|
-
return _this3.gc();
|
|
912
|
-
}, GC_INTERVAL);
|
|
913
|
-
} else {
|
|
914
|
-
this.timeoutId = 0;
|
|
915
|
-
}
|
|
916
|
-
};
|
|
917
|
-
|
|
918
|
-
module.exports = Pool;
|
|
919
|
-
|
|
920
|
-
},{}],14:[function(_dereq_,module,exports){
|
|
921
|
-
// Add intermediate resizing steps when scaling down by a very large factor.
|
|
922
|
-
//
|
|
923
|
-
// For example, when resizing 10000x10000 down to 10x10, it'll resize it to
|
|
924
|
-
// 300x300 first.
|
|
925
|
-
//
|
|
926
|
-
// It's needed because tiler has issues when the entire tile is scaled down
|
|
927
|
-
// to a few pixels (1024px source tile with border size 3 should result in
|
|
928
|
-
// at least 3+3+2 = 8px target tile, so max scale factor is 128 here).
|
|
929
|
-
//
|
|
930
|
-
// Also, adding intermediate steps can speed up processing if we use lower
|
|
931
|
-
// quality algorithms for first stages.
|
|
932
|
-
//
|
|
933
|
-
'use strict'; // min size = 0 results in infinite loop,
|
|
934
|
-
// min size = 1 can consume large amount of memory
|
|
935
|
-
|
|
936
|
-
var MIN_INNER_TILE_SIZE = 2;
|
|
937
|
-
|
|
938
|
-
module.exports = function createStages(fromWidth, fromHeight, toWidth, toHeight, srcTileSize, destTileBorder) {
|
|
939
|
-
var scaleX = toWidth / fromWidth;
|
|
940
|
-
var scaleY = toHeight / fromHeight; // derived from createRegions equation:
|
|
941
|
-
// innerTileWidth = pixelFloor(srcTileSize * scaleX) - 2 * destTileBorder;
|
|
942
|
-
|
|
943
|
-
var minScale = (2 * destTileBorder + MIN_INNER_TILE_SIZE + 1) / srcTileSize; // refuse to scale image multiple times by less than twice each time,
|
|
944
|
-
// it could only happen because of invalid options
|
|
945
|
-
|
|
946
|
-
if (minScale > 0.5) return [[toWidth, toHeight]];
|
|
947
|
-
var stageCount = Math.ceil(Math.log(Math.min(scaleX, scaleY)) / Math.log(minScale)); // no additional resizes are necessary,
|
|
948
|
-
// stageCount can be zero or be negative when enlarging the image
|
|
949
|
-
|
|
950
|
-
if (stageCount <= 1) return [[toWidth, toHeight]];
|
|
951
|
-
var result = [];
|
|
952
|
-
|
|
953
|
-
for (var i = 0; i < stageCount; i++) {
|
|
954
|
-
var width = Math.round(Math.pow(Math.pow(fromWidth, stageCount - i - 1) * Math.pow(toWidth, i + 1), 1 / stageCount));
|
|
955
|
-
var height = Math.round(Math.pow(Math.pow(fromHeight, stageCount - i - 1) * Math.pow(toHeight, i + 1), 1 / stageCount));
|
|
956
|
-
result.push([width, height]);
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
return result;
|
|
960
|
-
};
|
|
961
|
-
|
|
962
|
-
},{}],15:[function(_dereq_,module,exports){
|
|
963
|
-
// Split original image into multiple 1024x1024 chunks to reduce memory usage
|
|
964
|
-
// (images have to be unpacked into typed arrays for resizing) and allow
|
|
965
|
-
// parallel processing of multiple tiles at a time.
|
|
966
|
-
//
|
|
967
|
-
'use strict';
|
|
968
|
-
/*
|
|
969
|
-
* pixelFloor and pixelCeil are modified versions of Math.floor and Math.ceil
|
|
970
|
-
* functions which take into account floating point arithmetic errors.
|
|
971
|
-
* Those errors can cause undesired increments/decrements of sizes and offsets:
|
|
972
|
-
* Math.ceil(36 / (36 / 500)) = 501
|
|
973
|
-
* pixelCeil(36 / (36 / 500)) = 500
|
|
974
|
-
*/
|
|
975
|
-
|
|
976
|
-
var PIXEL_EPSILON = 1e-5;
|
|
977
|
-
|
|
978
|
-
function pixelFloor(x) {
|
|
979
|
-
var nearest = Math.round(x);
|
|
980
|
-
|
|
981
|
-
if (Math.abs(x - nearest) < PIXEL_EPSILON) {
|
|
982
|
-
return nearest;
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
return Math.floor(x);
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
function pixelCeil(x) {
|
|
989
|
-
var nearest = Math.round(x);
|
|
990
|
-
|
|
991
|
-
if (Math.abs(x - nearest) < PIXEL_EPSILON) {
|
|
992
|
-
return nearest;
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
return Math.ceil(x);
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
module.exports = function createRegions(options) {
|
|
999
|
-
var scaleX = options.toWidth / options.width;
|
|
1000
|
-
var scaleY = options.toHeight / options.height;
|
|
1001
|
-
var innerTileWidth = pixelFloor(options.srcTileSize * scaleX) - 2 * options.destTileBorder;
|
|
1002
|
-
var innerTileHeight = pixelFloor(options.srcTileSize * scaleY) - 2 * options.destTileBorder; // prevent infinite loop, this should never happen
|
|
1003
|
-
|
|
1004
|
-
if (innerTileWidth < 1 || innerTileHeight < 1) {
|
|
1005
|
-
throw new Error('Internal error in pica: target tile width/height is too small.');
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
var x, y;
|
|
1009
|
-
var innerX, innerY, toTileWidth, toTileHeight;
|
|
1010
|
-
var tiles = [];
|
|
1011
|
-
var tile; // we go top-to-down instead of left-to-right to make image displayed from top to
|
|
1012
|
-
// doesn in the browser
|
|
1013
|
-
|
|
1014
|
-
for (innerY = 0; innerY < options.toHeight; innerY += innerTileHeight) {
|
|
1015
|
-
for (innerX = 0; innerX < options.toWidth; innerX += innerTileWidth) {
|
|
1016
|
-
x = innerX - options.destTileBorder;
|
|
1017
|
-
|
|
1018
|
-
if (x < 0) {
|
|
1019
|
-
x = 0;
|
|
1020
|
-
}
|
|
1021
|
-
|
|
1022
|
-
toTileWidth = innerX + innerTileWidth + options.destTileBorder - x;
|
|
1023
|
-
|
|
1024
|
-
if (x + toTileWidth >= options.toWidth) {
|
|
1025
|
-
toTileWidth = options.toWidth - x;
|
|
1026
|
-
}
|
|
1027
|
-
|
|
1028
|
-
y = innerY - options.destTileBorder;
|
|
1029
|
-
|
|
1030
|
-
if (y < 0) {
|
|
1031
|
-
y = 0;
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
toTileHeight = innerY + innerTileHeight + options.destTileBorder - y;
|
|
1035
|
-
|
|
1036
|
-
if (y + toTileHeight >= options.toHeight) {
|
|
1037
|
-
toTileHeight = options.toHeight - y;
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
tile = {
|
|
1041
|
-
toX: x,
|
|
1042
|
-
toY: y,
|
|
1043
|
-
toWidth: toTileWidth,
|
|
1044
|
-
toHeight: toTileHeight,
|
|
1045
|
-
toInnerX: innerX,
|
|
1046
|
-
toInnerY: innerY,
|
|
1047
|
-
toInnerWidth: innerTileWidth,
|
|
1048
|
-
toInnerHeight: innerTileHeight,
|
|
1049
|
-
offsetX: x / scaleX - pixelFloor(x / scaleX),
|
|
1050
|
-
offsetY: y / scaleY - pixelFloor(y / scaleY),
|
|
1051
|
-
scaleX: scaleX,
|
|
1052
|
-
scaleY: scaleY,
|
|
1053
|
-
x: pixelFloor(x / scaleX),
|
|
1054
|
-
y: pixelFloor(y / scaleY),
|
|
1055
|
-
width: pixelCeil(toTileWidth / scaleX),
|
|
1056
|
-
height: pixelCeil(toTileHeight / scaleY)
|
|
1057
|
-
};
|
|
1058
|
-
tiles.push(tile);
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
|
|
1062
|
-
return tiles;
|
|
1063
|
-
};
|
|
1064
|
-
|
|
1065
|
-
},{}],16:[function(_dereq_,module,exports){
|
|
1066
|
-
'use strict';
|
|
1067
|
-
|
|
1068
|
-
function objClass(obj) {
|
|
1069
|
-
return Object.prototype.toString.call(obj);
|
|
1070
|
-
}
|
|
1071
|
-
|
|
1072
|
-
module.exports.isCanvas = function isCanvas(element) {
|
|
1073
|
-
var cname = objClass(element);
|
|
1074
|
-
return cname === '[object HTMLCanvasElement]'
|
|
1075
|
-
/* browser */
|
|
1076
|
-
|| cname === '[object OffscreenCanvas]' || cname === '[object Canvas]'
|
|
1077
|
-
/* node-canvas */
|
|
1078
|
-
;
|
|
1079
|
-
};
|
|
1080
|
-
|
|
1081
|
-
module.exports.isImage = function isImage(element) {
|
|
1082
|
-
return objClass(element) === '[object HTMLImageElement]';
|
|
1083
|
-
};
|
|
1084
|
-
|
|
1085
|
-
module.exports.isImageBitmap = function isImageBitmap(element) {
|
|
1086
|
-
return objClass(element) === '[object ImageBitmap]';
|
|
1087
|
-
};
|
|
1088
|
-
|
|
1089
|
-
module.exports.limiter = function limiter(concurrency) {
|
|
1090
|
-
var active = 0,
|
|
1091
|
-
queue = [];
|
|
1092
|
-
|
|
1093
|
-
function roll() {
|
|
1094
|
-
if (active < concurrency && queue.length) {
|
|
1095
|
-
active++;
|
|
1096
|
-
queue.shift()();
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
|
-
return function limit(fn) {
|
|
1101
|
-
return new Promise(function (resolve, reject) {
|
|
1102
|
-
queue.push(function () {
|
|
1103
|
-
fn().then(function (result) {
|
|
1104
|
-
resolve(result);
|
|
1105
|
-
active--;
|
|
1106
|
-
roll();
|
|
1107
|
-
}, function (err) {
|
|
1108
|
-
reject(err);
|
|
1109
|
-
active--;
|
|
1110
|
-
roll();
|
|
1111
|
-
});
|
|
1112
|
-
});
|
|
1113
|
-
roll();
|
|
1114
|
-
});
|
|
1115
|
-
};
|
|
1116
|
-
};
|
|
1117
|
-
|
|
1118
|
-
module.exports.cib_quality_name = function cib_quality_name(num) {
|
|
1119
|
-
switch (num) {
|
|
1120
|
-
case 0:
|
|
1121
|
-
return 'pixelated';
|
|
1122
|
-
|
|
1123
|
-
case 1:
|
|
1124
|
-
return 'low';
|
|
1125
|
-
|
|
1126
|
-
case 2:
|
|
1127
|
-
return 'medium';
|
|
1128
|
-
}
|
|
1129
|
-
|
|
1130
|
-
return 'high';
|
|
1131
|
-
};
|
|
1132
|
-
|
|
1133
|
-
module.exports.cib_support = function cib_support(createCanvas) {
|
|
1134
|
-
return Promise.resolve().then(function () {
|
|
1135
|
-
if (typeof createImageBitmap === 'undefined') {
|
|
1136
|
-
return false;
|
|
1137
|
-
}
|
|
1138
|
-
|
|
1139
|
-
var c = createCanvas(100, 100);
|
|
1140
|
-
return createImageBitmap(c, 0, 0, 100, 100, {
|
|
1141
|
-
resizeWidth: 10,
|
|
1142
|
-
resizeHeight: 10,
|
|
1143
|
-
resizeQuality: 'high'
|
|
1144
|
-
}).then(function (bitmap) {
|
|
1145
|
-
var status = bitmap.width === 10; // Branch below is filtered on upper level. We do not call resize
|
|
1146
|
-
// detection for basic ImageBitmap.
|
|
1147
|
-
//
|
|
1148
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap
|
|
1149
|
-
// old Crome 51 has ImageBitmap without .close(). Then this code
|
|
1150
|
-
// will throw and return 'false' as expected.
|
|
1151
|
-
//
|
|
1152
|
-
|
|
1153
|
-
bitmap.close();
|
|
1154
|
-
c = null;
|
|
1155
|
-
return status;
|
|
1156
|
-
});
|
|
1157
|
-
})["catch"](function () {
|
|
1158
|
-
return false;
|
|
1159
|
-
});
|
|
1160
|
-
};
|
|
1161
|
-
|
|
1162
|
-
module.exports.worker_offscreen_canvas_support = function worker_offscreen_canvas_support() {
|
|
1163
|
-
return new Promise(function (resolve, reject) {
|
|
1164
|
-
if (typeof OffscreenCanvas === 'undefined') {
|
|
1165
|
-
// if OffscreenCanvas is present, we assume browser supports Worker and built-in Promise as well
|
|
1166
|
-
resolve(false);
|
|
1167
|
-
return;
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
function workerPayload(self) {
|
|
1171
|
-
if (typeof createImageBitmap === 'undefined') {
|
|
1172
|
-
self.postMessage(false);
|
|
1173
|
-
return;
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
Promise.resolve().then(function () {
|
|
1177
|
-
var canvas = new OffscreenCanvas(10, 10); // test that 2d context can be used in worker
|
|
1178
|
-
|
|
1179
|
-
var ctx = canvas.getContext('2d');
|
|
1180
|
-
ctx.rect(0, 0, 1, 1); // test that cib can be used to return image bitmap from worker
|
|
1181
|
-
|
|
1182
|
-
return createImageBitmap(canvas, 0, 0, 1, 1);
|
|
1183
|
-
}).then(function () {
|
|
1184
|
-
return self.postMessage(true);
|
|
1185
|
-
}, function () {
|
|
1186
|
-
return self.postMessage(false);
|
|
1187
|
-
});
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
var code = btoa("(".concat(workerPayload.toString(), ")(self);"));
|
|
1191
|
-
var w = new Worker("data:text/javascript;base64,".concat(code));
|
|
1192
|
-
|
|
1193
|
-
w.onmessage = function (ev) {
|
|
1194
|
-
return resolve(ev.data);
|
|
1195
|
-
};
|
|
1196
|
-
|
|
1197
|
-
w.onerror = reject;
|
|
1198
|
-
}).then(function (result) {
|
|
1199
|
-
return result;
|
|
1200
|
-
}, function () {
|
|
1201
|
-
return false;
|
|
1202
|
-
});
|
|
1203
|
-
}; // Check if canvas.getContext('2d').getImageData can be used,
|
|
1204
|
-
// FireFox randomizes the output of that function in `privacy.resistFingerprinting` mode
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
module.exports.can_use_canvas = function can_use_canvas(createCanvas) {
|
|
1208
|
-
var usable = false;
|
|
1209
|
-
|
|
1210
|
-
try {
|
|
1211
|
-
var canvas = createCanvas(2, 1);
|
|
1212
|
-
var ctx = canvas.getContext('2d');
|
|
1213
|
-
var d = ctx.createImageData(2, 1);
|
|
1214
|
-
d.data[0] = 12;
|
|
1215
|
-
d.data[1] = 23;
|
|
1216
|
-
d.data[2] = 34;
|
|
1217
|
-
d.data[3] = 255;
|
|
1218
|
-
d.data[4] = 45;
|
|
1219
|
-
d.data[5] = 56;
|
|
1220
|
-
d.data[6] = 67;
|
|
1221
|
-
d.data[7] = 255;
|
|
1222
|
-
ctx.putImageData(d, 0, 0);
|
|
1223
|
-
d = null;
|
|
1224
|
-
d = ctx.getImageData(0, 0, 2, 1);
|
|
1225
|
-
|
|
1226
|
-
if (d.data[0] === 12 && d.data[1] === 23 && d.data[2] === 34 && d.data[3] === 255 && d.data[4] === 45 && d.data[5] === 56 && d.data[6] === 67 && d.data[7] === 255) {
|
|
1227
|
-
usable = true;
|
|
1228
|
-
}
|
|
1229
|
-
} catch (err) {}
|
|
1230
|
-
|
|
1231
|
-
return usable;
|
|
1232
|
-
}; // Check if createImageBitmap(img, sx, sy, sw, sh) signature works correctly
|
|
1233
|
-
// with JPEG images oriented with Exif;
|
|
1234
|
-
// https://bugs.chromium.org/p/chromium/issues/detail?id=1220671
|
|
1235
|
-
// TODO: remove after it's fixed in chrome for at least 2 releases
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
module.exports.cib_can_use_region = function cib_can_use_region() {
|
|
1239
|
-
return new Promise(function (resolve) {
|
|
1240
|
-
// `Image` check required for use in `ServiceWorker`
|
|
1241
|
-
if (typeof Image === 'undefined' || typeof createImageBitmap === 'undefined') {
|
|
1242
|
-
resolve(false);
|
|
1243
|
-
return;
|
|
1244
|
-
}
|
|
1245
|
-
|
|
1246
|
-
var image = new Image();
|
|
1247
|
-
image.src = 'data:image/jpeg;base64,' + '/9j/4QBiRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAYAAAEaAAUAAAABAAAASgEbAAUAA' + 'AABAAAAUgEoAAMAAAABAAIAAAITAAMAAAABAAEAAAAAAAAAAABIAAAAAQAAAEgAAAAB/9' + 'sAQwAEAwMEAwMEBAMEBQQEBQYKBwYGBgYNCQoICg8NEBAPDQ8OERMYFBESFxIODxUcFRc' + 'ZGRsbGxAUHR8dGh8YGhsa/9sAQwEEBQUGBQYMBwcMGhEPERoaGhoaGhoaGhoaGhoaGhoa' + 'GhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoa/8IAEQgAAQACAwERAAIRAQMRA' + 'f/EABQAAQAAAAAAAAAAAAAAAAAAAAf/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAA' + 'IQAxAAAAF/P//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAQUCf//EABQRAQAAAAA' + 'AAAAAAAAAAAAAAAD/2gAIAQMBAT8Bf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIB' + 'AT8Bf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEABj8Cf//EABQQAQAAAAAAAAAAA' + 'AAAAAAAAAD/2gAIAQEAAT8hf//aAAwDAQACAAMAAAAQH//EABQRAQAAAAAAAAAAAAAAAA' + 'AAAAD/2gAIAQMBAT8Qf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Qf//EABQ' + 'QAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8Qf//Z';
|
|
1248
|
-
|
|
1249
|
-
image.onload = function () {
|
|
1250
|
-
createImageBitmap(image, 0, 0, image.width, image.height).then(function (bitmap) {
|
|
1251
|
-
if (bitmap.width === image.width && bitmap.height === image.height) {
|
|
1252
|
-
resolve(true);
|
|
1253
|
-
} else {
|
|
1254
|
-
resolve(false);
|
|
1255
|
-
}
|
|
1256
|
-
}, function () {
|
|
1257
|
-
return resolve(false);
|
|
1258
|
-
});
|
|
1259
|
-
};
|
|
1260
|
-
|
|
1261
|
-
image.onerror = function () {
|
|
1262
|
-
return resolve(false);
|
|
1263
|
-
};
|
|
1264
|
-
});
|
|
1265
|
-
};
|
|
1266
|
-
|
|
1267
|
-
},{}],17:[function(_dereq_,module,exports){
|
|
1268
|
-
// Web Worker wrapper for image resize function
|
|
1269
|
-
'use strict';
|
|
1270
|
-
|
|
1271
|
-
module.exports = function () {
|
|
1272
|
-
var MathLib = _dereq_('./mathlib');
|
|
1273
|
-
|
|
1274
|
-
var mathLib;
|
|
1275
|
-
/* eslint-disable no-undef */
|
|
1276
|
-
|
|
1277
|
-
onmessage = function onmessage(ev) {
|
|
1278
|
-
var tileOpts = ev.data.opts;
|
|
1279
|
-
var returnBitmap = false;
|
|
1280
|
-
|
|
1281
|
-
if (!tileOpts.src && tileOpts.srcBitmap) {
|
|
1282
|
-
var canvas = new OffscreenCanvas(tileOpts.width, tileOpts.height);
|
|
1283
|
-
var ctx = canvas.getContext('2d');
|
|
1284
|
-
ctx.drawImage(tileOpts.srcBitmap, 0, 0);
|
|
1285
|
-
tileOpts.src = ctx.getImageData(0, 0, tileOpts.width, tileOpts.height).data;
|
|
1286
|
-
canvas.width = canvas.height = 0;
|
|
1287
|
-
canvas = null;
|
|
1288
|
-
tileOpts.srcBitmap.close();
|
|
1289
|
-
tileOpts.srcBitmap = null; // Temporary force out data to typed array, because Chrome have artefacts
|
|
1290
|
-
// https://github.com/nodeca/pica/issues/223
|
|
1291
|
-
// returnBitmap = true;
|
|
1292
|
-
}
|
|
1293
|
-
|
|
1294
|
-
if (!mathLib) mathLib = new MathLib(ev.data.features); // Use multimath's sync auto-init. Avoid Promise use in old browsers,
|
|
1295
|
-
// because polyfills are not propagated to webworker.
|
|
1296
|
-
|
|
1297
|
-
var data = mathLib.resizeAndUnsharp(tileOpts);
|
|
1298
|
-
|
|
1299
|
-
if (returnBitmap) {
|
|
1300
|
-
var toImageData = new ImageData(new Uint8ClampedArray(data), tileOpts.toWidth, tileOpts.toHeight);
|
|
1301
|
-
|
|
1302
|
-
var _canvas = new OffscreenCanvas(tileOpts.toWidth, tileOpts.toHeight);
|
|
1303
|
-
|
|
1304
|
-
var _ctx = _canvas.getContext('2d');
|
|
1305
|
-
|
|
1306
|
-
_ctx.putImageData(toImageData, 0, 0);
|
|
1307
|
-
|
|
1308
|
-
createImageBitmap(_canvas).then(function (bitmap) {
|
|
1309
|
-
postMessage({
|
|
1310
|
-
bitmap: bitmap
|
|
1311
|
-
}, [bitmap]);
|
|
1312
|
-
});
|
|
1313
|
-
} else {
|
|
1314
|
-
postMessage({
|
|
1315
|
-
data: data
|
|
1316
|
-
}, [data.buffer]);
|
|
1317
|
-
}
|
|
1318
|
-
};
|
|
1319
|
-
};
|
|
1320
|
-
|
|
1321
|
-
},{"./mathlib":1}],18:[function(_dereq_,module,exports){
|
|
1322
|
-
// Calculate Gaussian blur of an image using IIR filter
|
|
1323
|
-
// The method is taken from Intel's white paper and code example attached to it:
|
|
1324
|
-
// https://software.intel.com/en-us/articles/iir-gaussian-blur-filter
|
|
1325
|
-
// -implementation-using-intel-advanced-vector-extensions
|
|
1326
|
-
|
|
1327
|
-
var a0, a1, a2, a3, b1, b2, left_corner, right_corner;
|
|
1328
|
-
|
|
1329
|
-
function gaussCoef(sigma) {
|
|
1330
|
-
if (sigma < 0.5) {
|
|
1331
|
-
sigma = 0.5;
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1334
|
-
var a = Math.exp(0.726 * 0.726) / sigma,
|
|
1335
|
-
g1 = Math.exp(-a),
|
|
1336
|
-
g2 = Math.exp(-2 * a),
|
|
1337
|
-
k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2);
|
|
1338
|
-
|
|
1339
|
-
a0 = k;
|
|
1340
|
-
a1 = k * (a - 1) * g1;
|
|
1341
|
-
a2 = k * (a + 1) * g1;
|
|
1342
|
-
a3 = -k * g2;
|
|
1343
|
-
b1 = 2 * g1;
|
|
1344
|
-
b2 = -g2;
|
|
1345
|
-
left_corner = (a0 + a1) / (1 - b1 - b2);
|
|
1346
|
-
right_corner = (a2 + a3) / (1 - b1 - b2);
|
|
1347
|
-
|
|
1348
|
-
// Attempt to force type to FP32.
|
|
1349
|
-
return new Float32Array([ a0, a1, a2, a3, b1, b2, left_corner, right_corner ]);
|
|
1350
|
-
}
|
|
1351
|
-
|
|
1352
|
-
function convolveMono16(src, out, line, coeff, width, height) {
|
|
1353
|
-
// takes src image and writes the blurred and transposed result into out
|
|
1354
|
-
|
|
1355
|
-
var prev_src, curr_src, curr_out, prev_out, prev_prev_out;
|
|
1356
|
-
var src_index, out_index, line_index;
|
|
1357
|
-
var i, j;
|
|
1358
|
-
var coeff_a0, coeff_a1, coeff_b1, coeff_b2;
|
|
1359
|
-
|
|
1360
|
-
for (i = 0; i < height; i++) {
|
|
1361
|
-
src_index = i * width;
|
|
1362
|
-
out_index = i;
|
|
1363
|
-
line_index = 0;
|
|
1364
|
-
|
|
1365
|
-
// left to right
|
|
1366
|
-
prev_src = src[src_index];
|
|
1367
|
-
prev_prev_out = prev_src * coeff[6];
|
|
1368
|
-
prev_out = prev_prev_out;
|
|
1369
|
-
|
|
1370
|
-
coeff_a0 = coeff[0];
|
|
1371
|
-
coeff_a1 = coeff[1];
|
|
1372
|
-
coeff_b1 = coeff[4];
|
|
1373
|
-
coeff_b2 = coeff[5];
|
|
1374
|
-
|
|
1375
|
-
for (j = 0; j < width; j++) {
|
|
1376
|
-
curr_src = src[src_index];
|
|
1377
|
-
|
|
1378
|
-
curr_out = curr_src * coeff_a0 +
|
|
1379
|
-
prev_src * coeff_a1 +
|
|
1380
|
-
prev_out * coeff_b1 +
|
|
1381
|
-
prev_prev_out * coeff_b2;
|
|
1382
|
-
|
|
1383
|
-
prev_prev_out = prev_out;
|
|
1384
|
-
prev_out = curr_out;
|
|
1385
|
-
prev_src = curr_src;
|
|
1386
|
-
|
|
1387
|
-
line[line_index] = prev_out;
|
|
1388
|
-
line_index++;
|
|
1389
|
-
src_index++;
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
|
-
src_index--;
|
|
1393
|
-
line_index--;
|
|
1394
|
-
out_index += height * (width - 1);
|
|
1395
|
-
|
|
1396
|
-
// right to left
|
|
1397
|
-
prev_src = src[src_index];
|
|
1398
|
-
prev_prev_out = prev_src * coeff[7];
|
|
1399
|
-
prev_out = prev_prev_out;
|
|
1400
|
-
curr_src = prev_src;
|
|
1401
|
-
|
|
1402
|
-
coeff_a0 = coeff[2];
|
|
1403
|
-
coeff_a1 = coeff[3];
|
|
1404
|
-
|
|
1405
|
-
for (j = width - 1; j >= 0; j--) {
|
|
1406
|
-
curr_out = curr_src * coeff_a0 +
|
|
1407
|
-
prev_src * coeff_a1 +
|
|
1408
|
-
prev_out * coeff_b1 +
|
|
1409
|
-
prev_prev_out * coeff_b2;
|
|
1410
|
-
|
|
1411
|
-
prev_prev_out = prev_out;
|
|
1412
|
-
prev_out = curr_out;
|
|
1413
|
-
|
|
1414
|
-
prev_src = curr_src;
|
|
1415
|
-
curr_src = src[src_index];
|
|
1416
|
-
|
|
1417
|
-
out[out_index] = line[line_index] + prev_out;
|
|
1418
|
-
|
|
1419
|
-
src_index--;
|
|
1420
|
-
line_index--;
|
|
1421
|
-
out_index -= height;
|
|
1422
|
-
}
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
function blurMono16(src, width, height, radius) {
|
|
1428
|
-
// Quick exit on zero radius
|
|
1429
|
-
if (!radius) { return; }
|
|
1430
|
-
|
|
1431
|
-
var out = new Uint16Array(src.length),
|
|
1432
|
-
tmp_line = new Float32Array(Math.max(width, height));
|
|
1433
|
-
|
|
1434
|
-
var coeff = gaussCoef(radius);
|
|
1435
|
-
|
|
1436
|
-
convolveMono16(src, out, tmp_line, coeff, width, height, radius);
|
|
1437
|
-
convolveMono16(out, src, tmp_line, coeff, height, width, radius);
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
module.exports = blurMono16;
|
|
1441
|
-
|
|
1442
|
-
},{}],19:[function(_dereq_,module,exports){
|
|
1443
|
-
'use strict';
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
var assign = _dereq_('object-assign');
|
|
1447
|
-
var base64decode = _dereq_('./lib/base64decode');
|
|
1448
|
-
var hasWebAssembly = _dereq_('./lib/wa_detect');
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
var DEFAULT_OPTIONS = {
|
|
1452
|
-
js: true,
|
|
1453
|
-
wasm: true
|
|
1454
|
-
};
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
function MultiMath(options) {
|
|
1458
|
-
if (!(this instanceof MultiMath)) return new MultiMath(options);
|
|
1459
|
-
|
|
1460
|
-
var opts = assign({}, DEFAULT_OPTIONS, options || {});
|
|
1461
|
-
|
|
1462
|
-
this.options = opts;
|
|
1463
|
-
|
|
1464
|
-
this.__cache = {};
|
|
1465
|
-
|
|
1466
|
-
this.__init_promise = null;
|
|
1467
|
-
this.__modules = opts.modules || {};
|
|
1468
|
-
this.__memory = null;
|
|
1469
|
-
this.__wasm = {};
|
|
1470
|
-
|
|
1471
|
-
this.__isLE = ((new Uint32Array((new Uint8Array([ 1, 0, 0, 0 ])).buffer))[0] === 1);
|
|
1472
|
-
|
|
1473
|
-
if (!this.options.js && !this.options.wasm) {
|
|
1474
|
-
throw new Error('mathlib: at least "js" or "wasm" should be enabled');
|
|
1475
|
-
}
|
|
1476
|
-
}
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
MultiMath.prototype.has_wasm = hasWebAssembly;
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
MultiMath.prototype.use = function (module) {
|
|
1483
|
-
this.__modules[module.name] = module;
|
|
1484
|
-
|
|
1485
|
-
// Pin the best possible implementation
|
|
1486
|
-
if (this.options.wasm && this.has_wasm() && module.wasm_fn) {
|
|
1487
|
-
this[module.name] = module.wasm_fn;
|
|
1488
|
-
} else {
|
|
1489
|
-
this[module.name] = module.fn;
|
|
1490
|
-
}
|
|
1491
|
-
|
|
1492
|
-
return this;
|
|
1493
|
-
};
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
MultiMath.prototype.init = function () {
|
|
1497
|
-
if (this.__init_promise) return this.__init_promise;
|
|
1498
|
-
|
|
1499
|
-
if (!this.options.js && this.options.wasm && !this.has_wasm()) {
|
|
1500
|
-
return Promise.reject(new Error('mathlib: only "wasm" was enabled, but it\'s not supported'));
|
|
1501
|
-
}
|
|
1502
|
-
|
|
1503
|
-
var self = this;
|
|
1504
|
-
|
|
1505
|
-
this.__init_promise = Promise.all(Object.keys(self.__modules).map(function (name) {
|
|
1506
|
-
var module = self.__modules[name];
|
|
1507
|
-
|
|
1508
|
-
if (!self.options.wasm || !self.has_wasm() || !module.wasm_fn) return null;
|
|
1509
|
-
|
|
1510
|
-
// If already compiled - exit
|
|
1511
|
-
if (self.__wasm[name]) return null;
|
|
1512
|
-
|
|
1513
|
-
// Compile wasm source
|
|
1514
|
-
return WebAssembly.compile(self.__base64decode(module.wasm_src))
|
|
1515
|
-
.then(function (m) { self.__wasm[name] = m; });
|
|
1516
|
-
}))
|
|
1517
|
-
.then(function () { return self; });
|
|
1518
|
-
|
|
1519
|
-
return this.__init_promise;
|
|
1520
|
-
};
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
////////////////////////////////////////////////////////////////////////////////
|
|
1524
|
-
// Methods below are for internal use from plugins
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
// Simple decode base64 to typed array. Useful to load embedded webassembly
|
|
1528
|
-
// code. You probably don't need to call this method directly.
|
|
1529
|
-
//
|
|
1530
|
-
MultiMath.prototype.__base64decode = base64decode;
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
// Increase current memory to include specified number of bytes. Do nothing if
|
|
1534
|
-
// size is already ok. You probably don't need to call this method directly,
|
|
1535
|
-
// because it will be invoked from `.__instance()`.
|
|
1536
|
-
//
|
|
1537
|
-
MultiMath.prototype.__reallocate = function mem_grow_to(bytes) {
|
|
1538
|
-
if (!this.__memory) {
|
|
1539
|
-
this.__memory = new WebAssembly.Memory({
|
|
1540
|
-
initial: Math.ceil(bytes / (64 * 1024))
|
|
1541
|
-
});
|
|
1542
|
-
return this.__memory;
|
|
1543
|
-
}
|
|
1544
|
-
|
|
1545
|
-
var mem_size = this.__memory.buffer.byteLength;
|
|
1546
|
-
|
|
1547
|
-
if (mem_size < bytes) {
|
|
1548
|
-
this.__memory.grow(Math.ceil((bytes - mem_size) / (64 * 1024)));
|
|
1549
|
-
}
|
|
1550
|
-
|
|
1551
|
-
return this.__memory;
|
|
1552
|
-
};
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
// Returns instantinated webassembly item by name, with specified memory size
|
|
1556
|
-
// and environment.
|
|
1557
|
-
// - use cache if available
|
|
1558
|
-
// - do sync module init, if async init was not called earlier
|
|
1559
|
-
// - allocate memory if not enougth
|
|
1560
|
-
// - can export functions to webassembly via "env_extra",
|
|
1561
|
-
// for example, { exp: Math.exp }
|
|
1562
|
-
//
|
|
1563
|
-
MultiMath.prototype.__instance = function instance(name, memsize, env_extra) {
|
|
1564
|
-
if (memsize) this.__reallocate(memsize);
|
|
1565
|
-
|
|
1566
|
-
// If .init() was not called, do sync compile
|
|
1567
|
-
if (!this.__wasm[name]) {
|
|
1568
|
-
var module = this.__modules[name];
|
|
1569
|
-
this.__wasm[name] = new WebAssembly.Module(this.__base64decode(module.wasm_src));
|
|
1570
|
-
}
|
|
1571
|
-
|
|
1572
|
-
if (!this.__cache[name]) {
|
|
1573
|
-
var env_base = {
|
|
1574
|
-
memoryBase: 0,
|
|
1575
|
-
memory: this.__memory,
|
|
1576
|
-
tableBase: 0,
|
|
1577
|
-
table: new WebAssembly.Table({ initial: 0, element: 'anyfunc' })
|
|
1578
|
-
};
|
|
1579
|
-
|
|
1580
|
-
this.__cache[name] = new WebAssembly.Instance(this.__wasm[name], {
|
|
1581
|
-
env: assign(env_base, env_extra || {})
|
|
1582
|
-
});
|
|
1583
|
-
}
|
|
1584
|
-
|
|
1585
|
-
return this.__cache[name];
|
|
1586
|
-
};
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
// Helper to calculate memory aligh for pointers. Webassembly does not require
|
|
1590
|
-
// this, but you may wish to experiment. Default base = 8;
|
|
1591
|
-
//
|
|
1592
|
-
MultiMath.prototype.__align = function align(number, base) {
|
|
1593
|
-
base = base || 8;
|
|
1594
|
-
var reminder = number % base;
|
|
1595
|
-
return number + (reminder ? base - reminder : 0);
|
|
1596
|
-
};
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
module.exports = MultiMath;
|
|
1600
|
-
|
|
1601
|
-
},{"./lib/base64decode":20,"./lib/wa_detect":21,"object-assign":22}],20:[function(_dereq_,module,exports){
|
|
1602
|
-
// base64 decode str -> Uint8Array, to load WA modules
|
|
1603
|
-
//
|
|
1604
|
-
'use strict';
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
module.exports = function base64decode(str) {
|
|
1611
|
-
var input = str.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan
|
|
1612
|
-
max = input.length;
|
|
1613
|
-
|
|
1614
|
-
var out = new Uint8Array((max * 3) >> 2);
|
|
1615
|
-
|
|
1616
|
-
// Collect by 6*4 bits (3 bytes)
|
|
1617
|
-
|
|
1618
|
-
var bits = 0;
|
|
1619
|
-
var ptr = 0;
|
|
1620
|
-
|
|
1621
|
-
for (var idx = 0; idx < max; idx++) {
|
|
1622
|
-
if ((idx % 4 === 0) && idx) {
|
|
1623
|
-
out[ptr++] = (bits >> 16) & 0xFF;
|
|
1624
|
-
out[ptr++] = (bits >> 8) & 0xFF;
|
|
1625
|
-
out[ptr++] = bits & 0xFF;
|
|
1626
|
-
}
|
|
1627
|
-
|
|
1628
|
-
bits = (bits << 6) | BASE64_MAP.indexOf(input.charAt(idx));
|
|
1629
|
-
}
|
|
1630
|
-
|
|
1631
|
-
// Dump tail
|
|
1632
|
-
|
|
1633
|
-
var tailbits = (max % 4) * 6;
|
|
1634
|
-
|
|
1635
|
-
if (tailbits === 0) {
|
|
1636
|
-
out[ptr++] = (bits >> 16) & 0xFF;
|
|
1637
|
-
out[ptr++] = (bits >> 8) & 0xFF;
|
|
1638
|
-
out[ptr++] = bits & 0xFF;
|
|
1639
|
-
} else if (tailbits === 18) {
|
|
1640
|
-
out[ptr++] = (bits >> 10) & 0xFF;
|
|
1641
|
-
out[ptr++] = (bits >> 2) & 0xFF;
|
|
1642
|
-
} else if (tailbits === 12) {
|
|
1643
|
-
out[ptr++] = (bits >> 4) & 0xFF;
|
|
1644
|
-
}
|
|
1645
|
-
|
|
1646
|
-
return out;
|
|
1647
|
-
};
|
|
1648
|
-
|
|
1649
|
-
},{}],21:[function(_dereq_,module,exports){
|
|
1650
|
-
// Detect WebAssembly support.
|
|
1651
|
-
// - Check global WebAssembly object
|
|
1652
|
-
// - Try to load simple module (can be disabled via CSP)
|
|
1653
|
-
//
|
|
1654
|
-
'use strict';
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
var wa;
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
module.exports = function hasWebAssembly() {
|
|
1661
|
-
// use cache if called before;
|
|
1662
|
-
if (typeof wa !== 'undefined') return wa;
|
|
1663
|
-
|
|
1664
|
-
wa = false;
|
|
1665
|
-
|
|
1666
|
-
if (typeof WebAssembly === 'undefined') return wa;
|
|
1667
|
-
|
|
1668
|
-
// If WebAssenbly is disabled, code can throw on compile
|
|
1669
|
-
try {
|
|
1670
|
-
// https://github.com/brion/min-wasm-fail/blob/master/min-wasm-fail.in.js
|
|
1671
|
-
// Additional check that WA internals are correct
|
|
1672
|
-
|
|
1673
|
-
/* eslint-disable comma-spacing, max-len */
|
|
1674
|
-
var bin = new Uint8Array([ 0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,127,3,2,1,0,5,3,1,0,1,7,8,1,4,116,101,115,116,0,0,10,16,1,14,0,32,0,65,1,54,2,0,32,0,40,2,0,11 ]);
|
|
1675
|
-
var module = new WebAssembly.Module(bin);
|
|
1676
|
-
var instance = new WebAssembly.Instance(module, {});
|
|
1677
|
-
|
|
1678
|
-
// test storing to and loading from a non-zero location via a parameter.
|
|
1679
|
-
// Safari on iOS 11.2.5 returns 0 unexpectedly at non-zero locations
|
|
1680
|
-
if (instance.exports.test(4) !== 0) wa = true;
|
|
1681
|
-
|
|
1682
|
-
return wa;
|
|
1683
|
-
} catch (__) {}
|
|
1684
|
-
|
|
1685
|
-
return wa;
|
|
1686
|
-
};
|
|
1687
|
-
|
|
1688
|
-
},{}],22:[function(_dereq_,module,exports){
|
|
1689
|
-
/*
|
|
1690
|
-
object-assign
|
|
1691
|
-
(c) Sindre Sorhus
|
|
1692
|
-
@license MIT
|
|
1693
|
-
*/
|
|
1694
|
-
|
|
1695
|
-
'use strict';
|
|
1696
|
-
/* eslint-disable no-unused-vars */
|
|
1697
|
-
var getOwnPropertySymbols = Object.getOwnPropertySymbols;
|
|
1698
|
-
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
1699
|
-
var propIsEnumerable = Object.prototype.propertyIsEnumerable;
|
|
1700
|
-
|
|
1701
|
-
function toObject(val) {
|
|
1702
|
-
if (val === null || val === undefined) {
|
|
1703
|
-
throw new TypeError('Object.assign cannot be called with null or undefined');
|
|
7
|
+
(function(global, factory) {
|
|
8
|
+
typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define([], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, global.pica = factory());
|
|
9
|
+
})(this, function() {
|
|
10
|
+
var BASE64_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
11
|
+
function base64decode(str) {
|
|
12
|
+
const input = str.replace(/[\r\n=]/g, ""), max = input.length;
|
|
13
|
+
const out = new Uint8Array(max * 3 >> 2);
|
|
14
|
+
let bits = 0;
|
|
15
|
+
let ptr = 0;
|
|
16
|
+
for (let idx = 0; idx < max; idx++) {
|
|
17
|
+
if (idx % 4 === 0 && idx) {
|
|
18
|
+
out[ptr++] = bits >> 16 & 255;
|
|
19
|
+
out[ptr++] = bits >> 8 & 255;
|
|
20
|
+
out[ptr++] = bits & 255;
|
|
21
|
+
}
|
|
22
|
+
bits = bits << 6 | BASE64_MAP.indexOf(input.charAt(idx));
|
|
23
|
+
}
|
|
24
|
+
const tailbits = max % 4 * 6;
|
|
25
|
+
if (tailbits === 0) {
|
|
26
|
+
out[ptr++] = bits >> 16 & 255;
|
|
27
|
+
out[ptr++] = bits >> 8 & 255;
|
|
28
|
+
out[ptr++] = bits & 255;
|
|
29
|
+
} else if (tailbits === 18) {
|
|
30
|
+
out[ptr++] = bits >> 10 & 255;
|
|
31
|
+
out[ptr++] = bits >> 2 & 255;
|
|
32
|
+
} else if (tailbits === 12) out[ptr++] = bits >> 4 & 255;
|
|
33
|
+
return out;
|
|
1704
34
|
}
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
35
|
+
var wa;
|
|
36
|
+
function hasWebAssembly() {
|
|
37
|
+
if (typeof wa !== "undefined") return wa;
|
|
38
|
+
wa = false;
|
|
39
|
+
if (typeof WebAssembly === "undefined") return wa;
|
|
40
|
+
try {
|
|
41
|
+
const bin = new Uint8Array([
|
|
42
|
+
0,
|
|
43
|
+
97,
|
|
44
|
+
115,
|
|
45
|
+
109,
|
|
46
|
+
1,
|
|
47
|
+
0,
|
|
48
|
+
0,
|
|
49
|
+
0,
|
|
50
|
+
1,
|
|
51
|
+
6,
|
|
52
|
+
1,
|
|
53
|
+
96,
|
|
54
|
+
1,
|
|
55
|
+
127,
|
|
56
|
+
1,
|
|
57
|
+
127,
|
|
58
|
+
3,
|
|
59
|
+
2,
|
|
60
|
+
1,
|
|
61
|
+
0,
|
|
62
|
+
5,
|
|
63
|
+
3,
|
|
64
|
+
1,
|
|
65
|
+
0,
|
|
66
|
+
1,
|
|
67
|
+
7,
|
|
68
|
+
8,
|
|
69
|
+
1,
|
|
70
|
+
4,
|
|
71
|
+
116,
|
|
72
|
+
101,
|
|
73
|
+
115,
|
|
74
|
+
116,
|
|
75
|
+
0,
|
|
76
|
+
0,
|
|
77
|
+
10,
|
|
78
|
+
16,
|
|
79
|
+
1,
|
|
80
|
+
14,
|
|
81
|
+
0,
|
|
82
|
+
32,
|
|
83
|
+
0,
|
|
84
|
+
65,
|
|
85
|
+
1,
|
|
86
|
+
54,
|
|
87
|
+
2,
|
|
88
|
+
0,
|
|
89
|
+
32,
|
|
90
|
+
0,
|
|
91
|
+
40,
|
|
92
|
+
2,
|
|
93
|
+
0,
|
|
94
|
+
11
|
|
95
|
+
]);
|
|
96
|
+
const module = new WebAssembly.Module(bin);
|
|
97
|
+
if (new WebAssembly.Instance(module, {}).exports.test(4) !== 0) wa = true;
|
|
98
|
+
return wa;
|
|
99
|
+
} catch (__) {}
|
|
100
|
+
return wa;
|
|
101
|
+
}
|
|
102
|
+
var DEFAULT_OPTIONS = {
|
|
103
|
+
js: true,
|
|
104
|
+
wasm: true
|
|
105
|
+
};
|
|
106
|
+
var MultiMath = class {
|
|
107
|
+
constructor(options) {
|
|
108
|
+
const opts = Object.assign({}, DEFAULT_OPTIONS, options || {});
|
|
109
|
+
this.options = opts;
|
|
110
|
+
this.__cache = {};
|
|
111
|
+
this.__init_promise = null;
|
|
112
|
+
this.__modules = opts.modules || {};
|
|
113
|
+
this.__memory = null;
|
|
114
|
+
this.__wasm = {};
|
|
115
|
+
this.__isLE = new Uint32Array(new Uint8Array([
|
|
116
|
+
1,
|
|
117
|
+
0,
|
|
118
|
+
0,
|
|
119
|
+
0
|
|
120
|
+
]).buffer)[0] === 1;
|
|
121
|
+
if (!this.options.js && !this.options.wasm) throw new Error("mathlib: at least \"js\" or \"wasm\" should be enabled");
|
|
122
|
+
}
|
|
123
|
+
has_wasm() {
|
|
124
|
+
return hasWebAssembly();
|
|
125
|
+
}
|
|
126
|
+
use(module) {
|
|
127
|
+
this.__modules[module.name] = module;
|
|
128
|
+
if (this.options.wasm && this.has_wasm() && module.wasm_fn) this[module.name] = module.wasm_fn;
|
|
129
|
+
else this[module.name] = module.fn;
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
init() {
|
|
133
|
+
if (this.__init_promise) return this.__init_promise;
|
|
134
|
+
if (!this.options.js && this.options.wasm && !this.has_wasm()) return Promise.reject(/* @__PURE__ */ new Error("mathlib: only \"wasm\" was enabled, but it's not supported"));
|
|
135
|
+
this.__init_promise = Promise.all(Object.keys(this.__modules).map((name) => {
|
|
136
|
+
const module = this.__modules[name];
|
|
137
|
+
if (!this.options.wasm || !this.has_wasm() || !module.wasm_fn) return null;
|
|
138
|
+
if (this.__wasm[name]) return null;
|
|
139
|
+
return WebAssembly.compile(base64decode(module.wasm_src)).then((m) => {
|
|
140
|
+
this.__wasm[name] = m;
|
|
141
|
+
});
|
|
142
|
+
})).then(() => this);
|
|
143
|
+
return this.__init_promise;
|
|
144
|
+
}
|
|
145
|
+
__reallocate(bytes) {
|
|
146
|
+
if (!this.__memory) {
|
|
147
|
+
this.__memory = new WebAssembly.Memory({ initial: Math.ceil(bytes / (64 * 1024)) });
|
|
148
|
+
return this.__memory;
|
|
149
|
+
}
|
|
150
|
+
const mem_size = this.__memory.buffer.byteLength;
|
|
151
|
+
if (mem_size < bytes) this.__memory.grow(Math.ceil((bytes - mem_size) / (64 * 1024)));
|
|
152
|
+
return this.__memory;
|
|
153
|
+
}
|
|
154
|
+
__instance(name, memsize, env_extra) {
|
|
155
|
+
if (memsize) this.__reallocate(memsize);
|
|
156
|
+
if (!this.__wasm[name]) {
|
|
157
|
+
const module = this.__modules[name];
|
|
158
|
+
this.__wasm[name] = new WebAssembly.Module(base64decode(module.wasm_src));
|
|
159
|
+
}
|
|
160
|
+
if (!this.__cache[name]) {
|
|
161
|
+
const env_base = {
|
|
162
|
+
memoryBase: 0,
|
|
163
|
+
memory: this.__memory,
|
|
164
|
+
tableBase: 0,
|
|
165
|
+
table: new WebAssembly.Table({
|
|
166
|
+
initial: 0,
|
|
167
|
+
element: "anyfunc"
|
|
168
|
+
})
|
|
169
|
+
};
|
|
170
|
+
this.__cache[name] = new WebAssembly.Instance(this.__wasm[name], { env: Object.assign(env_base, env_extra || {}) });
|
|
171
|
+
}
|
|
172
|
+
return this.__cache[name];
|
|
173
|
+
}
|
|
174
|
+
__align(number, base) {
|
|
175
|
+
base = base || 8;
|
|
176
|
+
const reminder = number % base;
|
|
177
|
+
return number + (reminder ? base - reminder : 0);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
function gaussCoef(sigma) {
|
|
181
|
+
if (sigma < .5) sigma = .5;
|
|
182
|
+
const a = Math.exp(.726 * .726) / sigma, g1 = Math.exp(-a), g2 = Math.exp(-2 * a), k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2);
|
|
183
|
+
const a0 = k;
|
|
184
|
+
const a1 = k * (a - 1) * g1;
|
|
185
|
+
const a2 = k * (a + 1) * g1;
|
|
186
|
+
const a3 = -k * g2;
|
|
187
|
+
const b1 = 2 * g1;
|
|
188
|
+
const b2 = -g2;
|
|
189
|
+
const left_corner = (a0 + a1) / (1 - b1 - b2);
|
|
190
|
+
const right_corner = (a2 + a3) / (1 - b1 - b2);
|
|
191
|
+
return new Float32Array([
|
|
192
|
+
a0,
|
|
193
|
+
a1,
|
|
194
|
+
a2,
|
|
195
|
+
a3,
|
|
196
|
+
b1,
|
|
197
|
+
b2,
|
|
198
|
+
left_corner,
|
|
199
|
+
right_corner
|
|
200
|
+
]);
|
|
201
|
+
}
|
|
202
|
+
function convolveMono16(src, out, line, coeff, width, height) {
|
|
203
|
+
let prev_src, curr_src, curr_out, prev_out, prev_prev_out;
|
|
204
|
+
let src_index, out_index, line_index;
|
|
205
|
+
let i, j;
|
|
206
|
+
let coeff_a0, coeff_a1, coeff_b1, coeff_b2;
|
|
207
|
+
for (i = 0; i < height; i++) {
|
|
208
|
+
src_index = i * width;
|
|
209
|
+
out_index = i;
|
|
210
|
+
line_index = 0;
|
|
211
|
+
prev_src = src[src_index];
|
|
212
|
+
prev_prev_out = prev_src * coeff[6];
|
|
213
|
+
prev_out = prev_prev_out;
|
|
214
|
+
coeff_a0 = coeff[0];
|
|
215
|
+
coeff_a1 = coeff[1];
|
|
216
|
+
coeff_b1 = coeff[4];
|
|
217
|
+
coeff_b2 = coeff[5];
|
|
218
|
+
for (j = 0; j < width; j++) {
|
|
219
|
+
curr_src = src[src_index];
|
|
220
|
+
curr_out = curr_src * coeff_a0 + prev_src * coeff_a1 + prev_out * coeff_b1 + prev_prev_out * coeff_b2;
|
|
221
|
+
prev_prev_out = prev_out;
|
|
222
|
+
prev_out = curr_out;
|
|
223
|
+
prev_src = curr_src;
|
|
224
|
+
line[line_index] = prev_out;
|
|
225
|
+
line_index++;
|
|
226
|
+
src_index++;
|
|
227
|
+
}
|
|
228
|
+
src_index--;
|
|
229
|
+
line_index--;
|
|
230
|
+
out_index += height * (width - 1);
|
|
231
|
+
prev_src = src[src_index];
|
|
232
|
+
prev_prev_out = prev_src * coeff[7];
|
|
233
|
+
prev_out = prev_prev_out;
|
|
234
|
+
curr_src = prev_src;
|
|
235
|
+
coeff_a0 = coeff[2];
|
|
236
|
+
coeff_a1 = coeff[3];
|
|
237
|
+
for (j = width - 1; j >= 0; j--) {
|
|
238
|
+
curr_out = curr_src * coeff_a0 + prev_src * coeff_a1 + prev_out * coeff_b1 + prev_prev_out * coeff_b2;
|
|
239
|
+
prev_prev_out = prev_out;
|
|
240
|
+
prev_out = curr_out;
|
|
241
|
+
prev_src = curr_src;
|
|
242
|
+
curr_src = src[src_index];
|
|
243
|
+
out[out_index] = line[line_index] + prev_out;
|
|
244
|
+
src_index--;
|
|
245
|
+
line_index--;
|
|
246
|
+
out_index -= height;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function blurMono16(src, width, height, radius) {
|
|
251
|
+
if (!radius) return;
|
|
252
|
+
const out = new Uint16Array(src.length), tmp_line = new Float32Array(Math.max(width, height));
|
|
253
|
+
const coeff = gaussCoef(radius);
|
|
254
|
+
convolveMono16(src, out, tmp_line, coeff, width, height, radius);
|
|
255
|
+
convolveMono16(out, src, tmp_line, coeff, height, width, radius);
|
|
256
|
+
}
|
|
257
|
+
function hsv_v16(img, width, height) {
|
|
258
|
+
const size = width * height;
|
|
259
|
+
const out = new Uint16Array(size);
|
|
260
|
+
let r, g, b, max;
|
|
261
|
+
for (let i = 0; i < size; i++) {
|
|
262
|
+
r = img[4 * i];
|
|
263
|
+
g = img[4 * i + 1];
|
|
264
|
+
b = img[4 * i + 2];
|
|
265
|
+
max = r >= g && r >= b ? r : g >= b && g >= r ? g : b;
|
|
266
|
+
out[i] = max << 8;
|
|
267
|
+
}
|
|
268
|
+
return out;
|
|
269
|
+
}
|
|
270
|
+
function unsharp$1(img, width, height, amount, radius, threshold) {
|
|
271
|
+
let v1, v2, vmul;
|
|
272
|
+
let diff, iTimes4;
|
|
273
|
+
if (amount === 0 || radius < .5) return;
|
|
274
|
+
if (radius > 2) radius = 2;
|
|
275
|
+
const brightness = hsv_v16(img, width, height);
|
|
276
|
+
const blured = new Uint16Array(brightness);
|
|
277
|
+
blurMono16(blured, width, height, radius);
|
|
278
|
+
const amountFp = amount / 100 * 4096 + .5 | 0;
|
|
279
|
+
const thresholdFp = threshold << 8;
|
|
280
|
+
const size = width * height;
|
|
281
|
+
for (let i = 0; i < size; i++) {
|
|
282
|
+
v1 = brightness[i];
|
|
283
|
+
diff = v1 - blured[i];
|
|
284
|
+
if (Math.abs(diff) >= thresholdFp) {
|
|
285
|
+
v2 = v1 + (amountFp * diff + 2048 >> 12);
|
|
286
|
+
v2 = v2 > 65280 ? 65280 : v2;
|
|
287
|
+
v2 = v2 < 0 ? 0 : v2;
|
|
288
|
+
v1 = v1 !== 0 ? v1 : 1;
|
|
289
|
+
vmul = (v2 << 12) / v1 | 0;
|
|
290
|
+
iTimes4 = i * 4;
|
|
291
|
+
img[iTimes4] = img[iTimes4] * vmul + 2048 >> 12;
|
|
292
|
+
img[iTimes4 + 1] = img[iTimes4 + 1] * vmul + 2048 >> 12;
|
|
293
|
+
img[iTimes4 + 2] = img[iTimes4 + 2] * vmul + 2048 >> 12;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
function unsharp(img, width, height, amount, radius, threshold) {
|
|
298
|
+
if (amount === 0 || radius < .5) return;
|
|
299
|
+
if (radius > 2) radius = 2;
|
|
300
|
+
const pixels = width * height;
|
|
301
|
+
const img_bytes_cnt = pixels * 4;
|
|
302
|
+
const hsv_bytes_cnt = pixels * 2;
|
|
303
|
+
const blur_bytes_cnt = pixels * 2;
|
|
304
|
+
const blur_line_byte_cnt = Math.max(width, height) * 4;
|
|
305
|
+
const blur_coeffs_byte_cnt = 32;
|
|
306
|
+
const img_offset = 0;
|
|
307
|
+
const hsv_offset = img_bytes_cnt;
|
|
308
|
+
const blur_offset = hsv_offset + hsv_bytes_cnt;
|
|
309
|
+
const blur_tmp_offset = blur_offset + blur_bytes_cnt;
|
|
310
|
+
const blur_line_offset = blur_tmp_offset + blur_bytes_cnt;
|
|
311
|
+
const blur_coeffs_offset = blur_line_offset + blur_line_byte_cnt;
|
|
312
|
+
const instance = this.__instance("unsharp_mask", img_bytes_cnt + hsv_bytes_cnt + blur_bytes_cnt * 2 + blur_line_byte_cnt + blur_coeffs_byte_cnt, { exp: Math.exp });
|
|
313
|
+
const img32 = new Uint32Array(img.buffer);
|
|
314
|
+
new Uint32Array(this.__memory.buffer).set(img32);
|
|
315
|
+
let fn = instance.exports.hsv_v16 || instance.exports._hsv_v16;
|
|
316
|
+
if (!fn) throw new Error("WASM hsv_v16 function is not available");
|
|
317
|
+
fn(img_offset, hsv_offset, width, height);
|
|
318
|
+
fn = instance.exports.blurMono16 || instance.exports._blurMono16;
|
|
319
|
+
if (!fn) throw new Error("WASM blurMono16 function is not available");
|
|
320
|
+
fn(hsv_offset, blur_offset, blur_tmp_offset, blur_line_offset, blur_coeffs_offset, width, height, radius);
|
|
321
|
+
fn = instance.exports.unsharp || instance.exports._unsharp;
|
|
322
|
+
if (!fn) throw new Error("WASM unsharp function is not available");
|
|
323
|
+
fn(img_offset, img_offset, hsv_offset, blur_offset, width, height, amount, threshold);
|
|
324
|
+
img32.set(new Uint32Array(this.__memory.buffer, 0, pixels));
|
|
325
|
+
}
|
|
326
|
+
var mm_unsharp_mask_default = {
|
|
327
|
+
name: "unsharp_mask",
|
|
328
|
+
fn: unsharp$1,
|
|
329
|
+
wasm_fn: unsharp,
|
|
330
|
+
wasm_src: "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"
|
|
331
|
+
};
|
|
332
|
+
var resize_filter_info_default = { filter: {
|
|
333
|
+
box: {
|
|
334
|
+
win: .5,
|
|
335
|
+
fn(x) {
|
|
336
|
+
if (x < 0) x = -x;
|
|
337
|
+
return x < .5 ? 1 : 0;
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
hamming: {
|
|
341
|
+
win: 1,
|
|
342
|
+
fn(x) {
|
|
343
|
+
if (x < 0) x = -x;
|
|
344
|
+
if (x >= 1) return 0;
|
|
345
|
+
if (x < 1.1920929e-7) return 1;
|
|
346
|
+
const xpi = x * Math.PI;
|
|
347
|
+
return Math.sin(xpi) / xpi * (.54 + .46 * Math.cos(xpi / 1));
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
lanczos2: {
|
|
351
|
+
win: 2,
|
|
352
|
+
fn(x) {
|
|
353
|
+
if (x < 0) x = -x;
|
|
354
|
+
if (x >= 2) return 0;
|
|
355
|
+
if (x < 1.1920929e-7) return 1;
|
|
356
|
+
const xpi = x * Math.PI;
|
|
357
|
+
return Math.sin(xpi) / xpi * Math.sin(xpi / 2) / (xpi / 2);
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
lanczos3: {
|
|
361
|
+
win: 3,
|
|
362
|
+
fn(x) {
|
|
363
|
+
if (x < 0) x = -x;
|
|
364
|
+
if (x >= 3) return 0;
|
|
365
|
+
if (x < 1.1920929e-7) return 1;
|
|
366
|
+
const xpi = x * Math.PI;
|
|
367
|
+
return Math.sin(xpi) / xpi * Math.sin(xpi / 3) / (xpi / 3);
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
mks2013: {
|
|
371
|
+
win: 2.5,
|
|
372
|
+
fn(x) {
|
|
373
|
+
if (x < 0) x = -x;
|
|
374
|
+
if (x >= 2.5) return 0;
|
|
375
|
+
if (x >= 1.5) return -.125 * (x - 2.5) * (x - 2.5);
|
|
376
|
+
if (x >= .5) return .25 * (4 * x * x - 11 * x + 7);
|
|
377
|
+
return 1.0625 - 1.75 * x * x;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
} };
|
|
381
|
+
var FIXED_FRAC_BITS = 14;
|
|
382
|
+
function toFixedPoint(num) {
|
|
383
|
+
return Math.round(num * ((1 << FIXED_FRAC_BITS) - 1));
|
|
384
|
+
}
|
|
385
|
+
function resizeFilterGen(filter, srcSize, destSize, scale, offset) {
|
|
386
|
+
const filterFunction = resize_filter_info_default.filter[filter].fn;
|
|
387
|
+
const scaleInverted = 1 / scale;
|
|
388
|
+
const scaleClamped = Math.min(1, scale);
|
|
389
|
+
const srcWindow = resize_filter_info_default.filter[filter].win / scaleClamped;
|
|
390
|
+
let destPixel, srcPixel, srcFirst, srcLast, filterElementSize, floatFilter, fxpFilter, total, pxl, idx, floatVal, filterTotal, filterVal;
|
|
391
|
+
let leftNotEmpty, rightNotEmpty, filterShift, filterSize;
|
|
392
|
+
const maxFilterElementSize = Math.floor((srcWindow + 1) * 2);
|
|
393
|
+
const packedFilter = new Int16Array((maxFilterElementSize + 2) * destSize);
|
|
394
|
+
let packedFilterPtr = 0;
|
|
395
|
+
const slowCopy = !packedFilter.subarray || !packedFilter.set;
|
|
396
|
+
for (destPixel = 0; destPixel < destSize; destPixel++) {
|
|
397
|
+
srcPixel = (destPixel + .5) * scaleInverted + offset;
|
|
398
|
+
srcFirst = Math.max(0, Math.floor(srcPixel - srcWindow));
|
|
399
|
+
srcLast = Math.min(srcSize - 1, Math.ceil(srcPixel + srcWindow));
|
|
400
|
+
filterElementSize = srcLast - srcFirst + 1;
|
|
401
|
+
floatFilter = new Float32Array(filterElementSize);
|
|
402
|
+
fxpFilter = new Int16Array(filterElementSize);
|
|
403
|
+
total = 0;
|
|
404
|
+
for (pxl = srcFirst, idx = 0; pxl <= srcLast; pxl++, idx++) {
|
|
405
|
+
floatVal = filterFunction((pxl + .5 - srcPixel) * scaleClamped);
|
|
406
|
+
total += floatVal;
|
|
407
|
+
floatFilter[idx] = floatVal;
|
|
408
|
+
}
|
|
409
|
+
filterTotal = 0;
|
|
410
|
+
for (idx = 0; idx < floatFilter.length; idx++) {
|
|
411
|
+
filterVal = floatFilter[idx] / total;
|
|
412
|
+
filterTotal += filterVal;
|
|
413
|
+
fxpFilter[idx] = toFixedPoint(filterVal);
|
|
414
|
+
}
|
|
415
|
+
fxpFilter[destSize >> 1] += toFixedPoint(1 - filterTotal);
|
|
416
|
+
leftNotEmpty = 0;
|
|
417
|
+
while (leftNotEmpty < fxpFilter.length && fxpFilter[leftNotEmpty] === 0) leftNotEmpty++;
|
|
418
|
+
if (leftNotEmpty < fxpFilter.length) {
|
|
419
|
+
rightNotEmpty = fxpFilter.length - 1;
|
|
420
|
+
while (rightNotEmpty > 0 && fxpFilter[rightNotEmpty] === 0) rightNotEmpty--;
|
|
421
|
+
filterShift = srcFirst + leftNotEmpty;
|
|
422
|
+
filterSize = rightNotEmpty - leftNotEmpty + 1;
|
|
423
|
+
packedFilter[packedFilterPtr++] = filterShift;
|
|
424
|
+
packedFilter[packedFilterPtr++] = filterSize;
|
|
425
|
+
if (!slowCopy) {
|
|
426
|
+
packedFilter.set(fxpFilter.subarray(leftNotEmpty, rightNotEmpty + 1), packedFilterPtr);
|
|
427
|
+
packedFilterPtr += filterSize;
|
|
428
|
+
} else for (idx = leftNotEmpty; idx <= rightNotEmpty; idx++) packedFilter[packedFilterPtr++] = fxpFilter[idx];
|
|
429
|
+
} else {
|
|
430
|
+
packedFilter[packedFilterPtr++] = 0;
|
|
431
|
+
packedFilter[packedFilterPtr++] = 0;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
return packedFilter;
|
|
435
|
+
}
|
|
436
|
+
function clampTo8(i) {
|
|
437
|
+
return i < 0 ? 0 : i > 255 ? 255 : i;
|
|
438
|
+
}
|
|
439
|
+
function clampNegative(i) {
|
|
440
|
+
return i >= 0 ? i : 0;
|
|
441
|
+
}
|
|
442
|
+
function convolveHor(src, dest, srcW, srcH, destW, filters) {
|
|
443
|
+
let r, g, b, a;
|
|
444
|
+
let filterPtr, filterShift, filterSize;
|
|
445
|
+
let srcPtr, srcY, destX, filterVal;
|
|
446
|
+
let srcOffset = 0, destOffset = 0;
|
|
447
|
+
for (srcY = 0; srcY < srcH; srcY++) {
|
|
448
|
+
filterPtr = 0;
|
|
449
|
+
for (destX = 0; destX < destW; destX++) {
|
|
450
|
+
filterShift = filters[filterPtr++];
|
|
451
|
+
filterSize = filters[filterPtr++];
|
|
452
|
+
srcPtr = srcOffset + filterShift * 4 | 0;
|
|
453
|
+
r = g = b = a = 0;
|
|
454
|
+
for (; filterSize > 0; filterSize--) {
|
|
455
|
+
filterVal = filters[filterPtr++];
|
|
456
|
+
a = a + filterVal * src[srcPtr + 3] | 0;
|
|
457
|
+
b = b + filterVal * src[srcPtr + 2] | 0;
|
|
458
|
+
g = g + filterVal * src[srcPtr + 1] | 0;
|
|
459
|
+
r = r + filterVal * src[srcPtr] | 0;
|
|
460
|
+
srcPtr = srcPtr + 4 | 0;
|
|
461
|
+
}
|
|
462
|
+
dest[destOffset + 3] = clampNegative(a >> 7);
|
|
463
|
+
dest[destOffset + 2] = clampNegative(b >> 7);
|
|
464
|
+
dest[destOffset + 1] = clampNegative(g >> 7);
|
|
465
|
+
dest[destOffset] = clampNegative(r >> 7);
|
|
466
|
+
destOffset = destOffset + srcH * 4 | 0;
|
|
467
|
+
}
|
|
468
|
+
destOffset = (srcY + 1) * 4 | 0;
|
|
469
|
+
srcOffset = (srcY + 1) * srcW * 4 | 0;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
function convolveVert(src, dest, srcW, srcH, destW, filters) {
|
|
473
|
+
let r, g, b, a;
|
|
474
|
+
let filterPtr, filterShift, filterSize;
|
|
475
|
+
let srcPtr, srcY, destX, filterVal;
|
|
476
|
+
let srcOffset = 0, destOffset = 0;
|
|
477
|
+
for (srcY = 0; srcY < srcH; srcY++) {
|
|
478
|
+
filterPtr = 0;
|
|
479
|
+
for (destX = 0; destX < destW; destX++) {
|
|
480
|
+
filterShift = filters[filterPtr++];
|
|
481
|
+
filterSize = filters[filterPtr++];
|
|
482
|
+
srcPtr = srcOffset + filterShift * 4 | 0;
|
|
483
|
+
r = g = b = a = 0;
|
|
484
|
+
for (; filterSize > 0; filterSize--) {
|
|
485
|
+
filterVal = filters[filterPtr++];
|
|
486
|
+
a = a + filterVal * src[srcPtr + 3] | 0;
|
|
487
|
+
b = b + filterVal * src[srcPtr + 2] | 0;
|
|
488
|
+
g = g + filterVal * src[srcPtr + 1] | 0;
|
|
489
|
+
r = r + filterVal * src[srcPtr] | 0;
|
|
490
|
+
srcPtr = srcPtr + 4 | 0;
|
|
491
|
+
}
|
|
492
|
+
r >>= 7;
|
|
493
|
+
g >>= 7;
|
|
494
|
+
b >>= 7;
|
|
495
|
+
a >>= 7;
|
|
496
|
+
dest[destOffset + 3] = clampTo8(a + 8192 >> 14);
|
|
497
|
+
dest[destOffset + 2] = clampTo8(b + 8192 >> 14);
|
|
498
|
+
dest[destOffset + 1] = clampTo8(g + 8192 >> 14);
|
|
499
|
+
dest[destOffset] = clampTo8(r + 8192 >> 14);
|
|
500
|
+
destOffset = destOffset + srcH * 4 | 0;
|
|
501
|
+
}
|
|
502
|
+
destOffset = (srcY + 1) * 4 | 0;
|
|
503
|
+
srcOffset = (srcY + 1) * srcW * 4 | 0;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
function convolveHorWithPre(src, dest, srcW, srcH, destW, filters) {
|
|
507
|
+
let r, g, b, a, alpha;
|
|
508
|
+
let filterPtr, filterShift, filterSize;
|
|
509
|
+
let srcPtr, srcY, destX, filterVal;
|
|
510
|
+
let srcOffset = 0, destOffset = 0;
|
|
511
|
+
for (srcY = 0; srcY < srcH; srcY++) {
|
|
512
|
+
filterPtr = 0;
|
|
513
|
+
for (destX = 0; destX < destW; destX++) {
|
|
514
|
+
filterShift = filters[filterPtr++];
|
|
515
|
+
filterSize = filters[filterPtr++];
|
|
516
|
+
srcPtr = srcOffset + filterShift * 4 | 0;
|
|
517
|
+
r = g = b = a = 0;
|
|
518
|
+
for (; filterSize > 0; filterSize--) {
|
|
519
|
+
filterVal = filters[filterPtr++];
|
|
520
|
+
alpha = src[srcPtr + 3];
|
|
521
|
+
a = a + filterVal * alpha | 0;
|
|
522
|
+
b = b + filterVal * src[srcPtr + 2] * alpha | 0;
|
|
523
|
+
g = g + filterVal * src[srcPtr + 1] * alpha | 0;
|
|
524
|
+
r = r + filterVal * src[srcPtr] * alpha | 0;
|
|
525
|
+
srcPtr = srcPtr + 4 | 0;
|
|
526
|
+
}
|
|
527
|
+
b = b / 255 | 0;
|
|
528
|
+
g = g / 255 | 0;
|
|
529
|
+
r = r / 255 | 0;
|
|
530
|
+
dest[destOffset + 3] = clampNegative(a >> 7);
|
|
531
|
+
dest[destOffset + 2] = clampNegative(b >> 7);
|
|
532
|
+
dest[destOffset + 1] = clampNegative(g >> 7);
|
|
533
|
+
dest[destOffset] = clampNegative(r >> 7);
|
|
534
|
+
destOffset = destOffset + srcH * 4 | 0;
|
|
535
|
+
}
|
|
536
|
+
destOffset = (srcY + 1) * 4 | 0;
|
|
537
|
+
srcOffset = (srcY + 1) * srcW * 4 | 0;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
function convolveVertWithPre(src, dest, srcW, srcH, destW, filters) {
|
|
541
|
+
let r, g, b, a;
|
|
542
|
+
let filterPtr, filterShift, filterSize;
|
|
543
|
+
let srcPtr, srcY, destX, filterVal;
|
|
544
|
+
let srcOffset = 0, destOffset = 0;
|
|
545
|
+
for (srcY = 0; srcY < srcH; srcY++) {
|
|
546
|
+
filterPtr = 0;
|
|
547
|
+
for (destX = 0; destX < destW; destX++) {
|
|
548
|
+
filterShift = filters[filterPtr++];
|
|
549
|
+
filterSize = filters[filterPtr++];
|
|
550
|
+
srcPtr = srcOffset + filterShift * 4 | 0;
|
|
551
|
+
r = g = b = a = 0;
|
|
552
|
+
for (; filterSize > 0; filterSize--) {
|
|
553
|
+
filterVal = filters[filterPtr++];
|
|
554
|
+
a = a + filterVal * src[srcPtr + 3] | 0;
|
|
555
|
+
b = b + filterVal * src[srcPtr + 2] | 0;
|
|
556
|
+
g = g + filterVal * src[srcPtr + 1] | 0;
|
|
557
|
+
r = r + filterVal * src[srcPtr] | 0;
|
|
558
|
+
srcPtr = srcPtr + 4 | 0;
|
|
559
|
+
}
|
|
560
|
+
r >>= 7;
|
|
561
|
+
g >>= 7;
|
|
562
|
+
b >>= 7;
|
|
563
|
+
a >>= 7;
|
|
564
|
+
a = clampTo8(a + 8192 >> 14);
|
|
565
|
+
if (a > 0) {
|
|
566
|
+
r = r * 255 / a | 0;
|
|
567
|
+
g = g * 255 / a | 0;
|
|
568
|
+
b = b * 255 / a | 0;
|
|
569
|
+
}
|
|
570
|
+
dest[destOffset + 3] = a;
|
|
571
|
+
dest[destOffset + 2] = clampTo8(b + 8192 >> 14);
|
|
572
|
+
dest[destOffset + 1] = clampTo8(g + 8192 >> 14);
|
|
573
|
+
dest[destOffset] = clampTo8(r + 8192 >> 14);
|
|
574
|
+
destOffset = destOffset + srcH * 4 | 0;
|
|
575
|
+
}
|
|
576
|
+
destOffset = (srcY + 1) * 4 | 0;
|
|
577
|
+
srcOffset = (srcY + 1) * srcW * 4 | 0;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
function hasAlpha$1(src, width, height) {
|
|
581
|
+
let ptr = 3;
|
|
582
|
+
const len = width * height * 4 | 0;
|
|
583
|
+
while (ptr < len) {
|
|
584
|
+
if (src[ptr] !== 255) return true;
|
|
585
|
+
ptr = ptr + 4 | 0;
|
|
586
|
+
}
|
|
587
|
+
return false;
|
|
588
|
+
}
|
|
589
|
+
function resetAlpha$1(dst, width, height) {
|
|
590
|
+
let ptr = 3;
|
|
591
|
+
const len = width * height * 4 | 0;
|
|
592
|
+
while (ptr < len) {
|
|
593
|
+
dst[ptr] = 255;
|
|
594
|
+
ptr = ptr + 4 | 0;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
function resize(options) {
|
|
598
|
+
const src = options.src;
|
|
599
|
+
const srcW = options.width;
|
|
600
|
+
const srcH = options.height;
|
|
601
|
+
const destW = options.toWidth;
|
|
602
|
+
const destH = options.toHeight;
|
|
603
|
+
const scaleX = options.scaleX || options.toWidth / options.width;
|
|
604
|
+
const scaleY = options.scaleY || options.toHeight / options.height;
|
|
605
|
+
const offsetX = options.offsetX || 0;
|
|
606
|
+
const offsetY = options.offsetY || 0;
|
|
607
|
+
const dest = options.dest || new Uint8Array(destW * destH * 4);
|
|
608
|
+
const filter = typeof options.filter === "undefined" ? "mks2013" : options.filter;
|
|
609
|
+
const filtersX = resizeFilterGen(filter, srcW, destW, scaleX, offsetX), filtersY = resizeFilterGen(filter, srcH, destH, scaleY, offsetY);
|
|
610
|
+
const tmp = new Uint16Array(destW * srcH * 4);
|
|
611
|
+
if (hasAlpha$1(src, srcW, srcH)) {
|
|
612
|
+
convolveHorWithPre(src, tmp, srcW, srcH, destW, filtersX);
|
|
613
|
+
convolveVertWithPre(tmp, dest, srcH, destW, destH, filtersY);
|
|
614
|
+
} else {
|
|
615
|
+
convolveHor(src, tmp, srcW, srcH, destW, filtersX);
|
|
616
|
+
convolveVert(tmp, dest, srcH, destW, destH, filtersY);
|
|
617
|
+
resetAlpha$1(dest, destW, destH);
|
|
618
|
+
}
|
|
619
|
+
return dest;
|
|
620
|
+
}
|
|
621
|
+
function hasAlpha(src, width, height) {
|
|
622
|
+
let ptr = 3;
|
|
623
|
+
const len = width * height * 4 | 0;
|
|
624
|
+
while (ptr < len) {
|
|
625
|
+
if (src[ptr] !== 255) return true;
|
|
626
|
+
ptr = ptr + 4 | 0;
|
|
627
|
+
}
|
|
628
|
+
return false;
|
|
629
|
+
}
|
|
630
|
+
function resetAlpha(dst, width, height) {
|
|
631
|
+
let ptr = 3;
|
|
632
|
+
const len = width * height * 4 | 0;
|
|
633
|
+
while (ptr < len) {
|
|
634
|
+
dst[ptr] = 255;
|
|
635
|
+
ptr = ptr + 4 | 0;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
function asUint8Array(src) {
|
|
639
|
+
return new Uint8Array(src.buffer, 0, src.byteLength);
|
|
640
|
+
}
|
|
641
|
+
var IS_LE = true;
|
|
1710
642
|
try {
|
|
1711
|
-
|
|
1712
|
-
|
|
643
|
+
IS_LE = new Uint32Array(new Uint8Array([
|
|
644
|
+
1,
|
|
645
|
+
0,
|
|
646
|
+
0,
|
|
647
|
+
0
|
|
648
|
+
]).buffer)[0] === 1;
|
|
649
|
+
} catch (__) {}
|
|
650
|
+
function copyInt16asLE(src, target, target_offset) {
|
|
651
|
+
if (IS_LE) {
|
|
652
|
+
target.set(asUint8Array(src), target_offset);
|
|
653
|
+
return;
|
|
1713
654
|
}
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
655
|
+
for (let ptr = target_offset, i = 0; i < src.length; i++) {
|
|
656
|
+
const data = src[i];
|
|
657
|
+
target[ptr++] = data & 255;
|
|
658
|
+
target[ptr++] = data >> 8 & 255;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
function resize_wasm(options) {
|
|
662
|
+
const src = options.src;
|
|
663
|
+
const srcW = options.width;
|
|
664
|
+
const srcH = options.height;
|
|
665
|
+
const destW = options.toWidth;
|
|
666
|
+
const destH = options.toHeight;
|
|
667
|
+
const scaleX = options.scaleX || options.toWidth / options.width;
|
|
668
|
+
const scaleY = options.scaleY || options.toHeight / options.height;
|
|
669
|
+
const offsetX = options.offsetX || 0;
|
|
670
|
+
const offsetY = options.offsetY || 0;
|
|
671
|
+
const dest = options.dest || new Uint8Array(destW * destH * 4);
|
|
672
|
+
const filter = typeof options.filter === "undefined" ? "mks2013" : options.filter;
|
|
673
|
+
const filtersX = resizeFilterGen(filter, srcW, destW, scaleX, offsetX), filtersY = resizeFilterGen(filter, srcH, destH, scaleY, offsetY);
|
|
674
|
+
const src_offset = 0;
|
|
675
|
+
const src_size = Math.max(src.byteLength, dest.byteLength);
|
|
676
|
+
const tmp_offset = this.__align(src_offset + src_size);
|
|
677
|
+
const tmp_size = srcH * destW * 4 * 2;
|
|
678
|
+
const filtersX_offset = this.__align(tmp_offset + tmp_size);
|
|
679
|
+
const filtersY_offset = this.__align(filtersX_offset + filtersX.byteLength);
|
|
680
|
+
const alloc_bytes = filtersY_offset + filtersY.byteLength;
|
|
681
|
+
const instance = this.__instance("resize", alloc_bytes);
|
|
682
|
+
const mem = new Uint8Array(this.__memory.buffer);
|
|
683
|
+
const mem32 = new Uint32Array(this.__memory.buffer);
|
|
684
|
+
const src32 = new Uint32Array(src.buffer);
|
|
685
|
+
mem32.set(src32);
|
|
686
|
+
copyInt16asLE(filtersX, mem, filtersX_offset);
|
|
687
|
+
copyInt16asLE(filtersY, mem, filtersY_offset);
|
|
688
|
+
const fn = instance.exports.convolveHV || instance.exports._convolveHV;
|
|
689
|
+
if (!fn) throw new Error("WASM resize function is not available");
|
|
690
|
+
if (hasAlpha(src, srcW, srcH)) fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH, 1);
|
|
691
|
+
else {
|
|
692
|
+
fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH, 0);
|
|
693
|
+
resetAlpha(dest, destW, destH);
|
|
694
|
+
}
|
|
695
|
+
new Uint32Array(dest.buffer).set(new Uint32Array(this.__memory.buffer, 0, destH * destW));
|
|
696
|
+
return dest;
|
|
697
|
+
}
|
|
698
|
+
var mm_resize_default = {
|
|
699
|
+
name: "resize",
|
|
700
|
+
fn: resize,
|
|
701
|
+
wasm_fn: resize_wasm,
|
|
702
|
+
wasm_src: "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"
|
|
703
|
+
};
|
|
704
|
+
var MathLib = class extends MultiMath {
|
|
705
|
+
constructor(requested_features) {
|
|
706
|
+
const __requested_features = requested_features || [];
|
|
707
|
+
const features = {
|
|
708
|
+
js: __requested_features.indexOf("js") >= 0,
|
|
709
|
+
wasm: __requested_features.indexOf("wasm") >= 0
|
|
710
|
+
};
|
|
711
|
+
super(features);
|
|
712
|
+
this.features = {
|
|
713
|
+
js: features.js,
|
|
714
|
+
wasm: features.wasm && this.has_wasm()
|
|
715
|
+
};
|
|
716
|
+
this.use(mm_unsharp_mask_default);
|
|
717
|
+
this.use(mm_resize_default);
|
|
718
|
+
}
|
|
719
|
+
resizeAndUnsharp(options) {
|
|
720
|
+
const result = this.resize(options);
|
|
721
|
+
if (options.unsharpAmount) this.unsharp_mask(result, options.toWidth, options.toHeight, options.unsharpAmount, options.unsharpRadius, options.unsharpThreshold);
|
|
722
|
+
return result;
|
|
723
|
+
}
|
|
724
|
+
};
|
|
725
|
+
function _typeof(o) {
|
|
726
|
+
"@babel/helpers - typeof";
|
|
727
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
728
|
+
return typeof o;
|
|
729
|
+
} : function(o) {
|
|
730
|
+
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
731
|
+
}, _typeof(o);
|
|
732
|
+
}
|
|
733
|
+
function toPrimitive(t, r) {
|
|
734
|
+
if ("object" != _typeof(t) || !t) return t;
|
|
735
|
+
var e = t[Symbol.toPrimitive];
|
|
736
|
+
if (void 0 !== e) {
|
|
737
|
+
var i = e.call(t, r || "default");
|
|
738
|
+
if ("object" != _typeof(i)) return i;
|
|
739
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
740
|
+
}
|
|
741
|
+
return ("string" === r ? String : Number)(t);
|
|
742
|
+
}
|
|
743
|
+
function toPropertyKey(t) {
|
|
744
|
+
var i = toPrimitive(t, "string");
|
|
745
|
+
return "symbol" == _typeof(i) ? i : i + "";
|
|
746
|
+
}
|
|
747
|
+
function _defineProperty(e, r, t) {
|
|
748
|
+
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
749
|
+
value: t,
|
|
750
|
+
enumerable: !0,
|
|
751
|
+
configurable: !0,
|
|
752
|
+
writable: !0
|
|
753
|
+
}) : e[r] = t, e;
|
|
754
|
+
}
|
|
755
|
+
function ownKeys(e, r) {
|
|
756
|
+
var t = Object.keys(e);
|
|
757
|
+
if (Object.getOwnPropertySymbols) {
|
|
758
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
759
|
+
r && (o = o.filter(function(r) {
|
|
760
|
+
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
761
|
+
})), t.push.apply(t, o);
|
|
762
|
+
}
|
|
763
|
+
return t;
|
|
764
|
+
}
|
|
765
|
+
function _objectSpread2(e) {
|
|
766
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
767
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
|
768
|
+
r % 2 ? ownKeys(Object(t), !0).forEach(function(r) {
|
|
769
|
+
_defineProperty(e, r, t[r]);
|
|
770
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r) {
|
|
771
|
+
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
return e;
|
|
775
|
+
}
|
|
776
|
+
var GC_INTERVAL = 100;
|
|
777
|
+
var Pool = class {
|
|
778
|
+
constructor(create, idle) {
|
|
779
|
+
_defineProperty(this, "create", void 0);
|
|
780
|
+
_defineProperty(this, "available", void 0);
|
|
781
|
+
_defineProperty(this, "acquired", void 0);
|
|
782
|
+
_defineProperty(this, "lastId", void 0);
|
|
783
|
+
_defineProperty(this, "timeoutId", void 0);
|
|
784
|
+
_defineProperty(this, "idle", void 0);
|
|
785
|
+
this.create = create;
|
|
786
|
+
this.available = [];
|
|
787
|
+
this.acquired = {};
|
|
788
|
+
this.lastId = 1;
|
|
789
|
+
this.timeoutId = 0;
|
|
790
|
+
this.idle = idle || 2e3;
|
|
791
|
+
}
|
|
792
|
+
acquire() {
|
|
793
|
+
let descriptor;
|
|
794
|
+
if (this.available.length !== 0) descriptor = this.available.pop();
|
|
795
|
+
else descriptor = _objectSpread2(_objectSpread2({}, this.create()), {}, {
|
|
796
|
+
id: this.lastId++,
|
|
797
|
+
lastUsed: 0
|
|
798
|
+
});
|
|
799
|
+
this.acquired[descriptor.id] = descriptor;
|
|
800
|
+
return {
|
|
801
|
+
value: descriptor.value,
|
|
802
|
+
release: () => this.release(descriptor)
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
release(descriptor) {
|
|
806
|
+
delete this.acquired[descriptor.id];
|
|
807
|
+
descriptor.lastUsed = Date.now();
|
|
808
|
+
this.available.push(descriptor);
|
|
809
|
+
if (this.timeoutId === 0) this.timeoutId = setTimeout(() => this.gc(), GC_INTERVAL);
|
|
810
|
+
}
|
|
811
|
+
gc() {
|
|
812
|
+
const now = Date.now();
|
|
813
|
+
this.available = this.available.filter((descriptor) => {
|
|
814
|
+
if (now - descriptor.lastUsed > this.idle) {
|
|
815
|
+
descriptor.destroy();
|
|
816
|
+
return false;
|
|
817
|
+
}
|
|
818
|
+
return true;
|
|
819
|
+
});
|
|
820
|
+
if (this.available.length !== 0) this.timeoutId = setTimeout(() => this.gc(), GC_INTERVAL);
|
|
821
|
+
else this.timeoutId = 0;
|
|
822
|
+
}
|
|
823
|
+
};
|
|
824
|
+
function objClass(obj) {
|
|
825
|
+
var _obj$constructor$name, _obj$constructor;
|
|
826
|
+
return (_obj$constructor$name = obj === null || obj === void 0 || (_obj$constructor = obj.constructor) === null || _obj$constructor === void 0 ? void 0 : _obj$constructor.name) !== null && _obj$constructor$name !== void 0 ? _obj$constructor$name : "";
|
|
827
|
+
}
|
|
828
|
+
function isCanvas(element) {
|
|
829
|
+
const cname = objClass(element);
|
|
830
|
+
return cname === "HTMLCanvasElement" || cname === "OffscreenCanvas" || cname === "Canvas" || cname === "CanvasElement";
|
|
831
|
+
}
|
|
832
|
+
function isImage(element) {
|
|
833
|
+
return objClass(element) === "HTMLImageElement";
|
|
834
|
+
}
|
|
835
|
+
function isImageBitmap(element) {
|
|
836
|
+
return objClass(element) === "ImageBitmap";
|
|
837
|
+
}
|
|
838
|
+
function limiter(concurrency) {
|
|
839
|
+
let active = 0;
|
|
840
|
+
const queue = [];
|
|
841
|
+
function roll() {
|
|
842
|
+
if (active < concurrency && queue.length) {
|
|
843
|
+
var _queue$shift;
|
|
844
|
+
active++;
|
|
845
|
+
(_queue$shift = queue.shift()) === null || _queue$shift === void 0 || _queue$shift();
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
return function limit(fn) {
|
|
849
|
+
return new Promise((resolve, reject) => {
|
|
850
|
+
queue.push(() => {
|
|
851
|
+
fn().then((result) => {
|
|
852
|
+
resolve(result);
|
|
853
|
+
active--;
|
|
854
|
+
roll();
|
|
855
|
+
}, (err) => {
|
|
856
|
+
reject(err);
|
|
857
|
+
active--;
|
|
858
|
+
roll();
|
|
859
|
+
});
|
|
860
|
+
});
|
|
861
|
+
roll();
|
|
862
|
+
});
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
function cib_quality_name(num) {
|
|
866
|
+
switch (num) {
|
|
867
|
+
case 0: return "pixelated";
|
|
868
|
+
case 1: return "low";
|
|
869
|
+
case 2: return "medium";
|
|
870
|
+
}
|
|
871
|
+
return "high";
|
|
872
|
+
}
|
|
873
|
+
var CIB_QUALITY_FILTERS = [
|
|
874
|
+
"box",
|
|
875
|
+
"hamming",
|
|
876
|
+
"lanczos2",
|
|
877
|
+
"lanczos3"
|
|
878
|
+
];
|
|
879
|
+
function cib_quality_filter(num) {
|
|
880
|
+
return CIB_QUALITY_FILTERS[num];
|
|
881
|
+
}
|
|
882
|
+
function is_cib_filter(filter) {
|
|
883
|
+
return CIB_QUALITY_FILTERS.indexOf(filter) >= 0;
|
|
884
|
+
}
|
|
885
|
+
function filter_to_cib_quality(filter) {
|
|
886
|
+
const index = CIB_QUALITY_FILTERS.indexOf(filter);
|
|
887
|
+
return index >= 0 ? index : void 0;
|
|
888
|
+
}
|
|
889
|
+
var MIN_INNER_TILE_SIZE = 2;
|
|
890
|
+
var DEST_TILE_BORDER = 3;
|
|
891
|
+
function createStages(fromWidth, fromHeight, toWidth, toHeight, srcTileSize) {
|
|
892
|
+
const scaleX = toWidth / fromWidth;
|
|
893
|
+
const scaleY = toHeight / fromHeight;
|
|
894
|
+
const minScale = (2 * DEST_TILE_BORDER + MIN_INNER_TILE_SIZE + 1) / srcTileSize;
|
|
895
|
+
if (minScale > .5) return [[toWidth, toHeight]];
|
|
896
|
+
const stageCount = Math.ceil(Math.log(Math.min(scaleX, scaleY)) / Math.log(minScale));
|
|
897
|
+
if (stageCount <= 1) return [[toWidth, toHeight]];
|
|
898
|
+
const result = [];
|
|
899
|
+
for (let i = 0; i < stageCount; i++) {
|
|
900
|
+
const width = Math.round(Math.pow(Math.pow(fromWidth, stageCount - i - 1) * Math.pow(toWidth, i + 1), 1 / stageCount));
|
|
901
|
+
const height = Math.round(Math.pow(Math.pow(fromHeight, stageCount - i - 1) * Math.pow(toHeight, i + 1), 1 / stageCount));
|
|
902
|
+
result.push([width, height]);
|
|
903
|
+
}
|
|
904
|
+
return result;
|
|
905
|
+
}
|
|
906
|
+
var PIXEL_EPSILON = 1e-5;
|
|
907
|
+
function pixelFloor(x) {
|
|
908
|
+
const nearest = Math.round(x);
|
|
909
|
+
if (Math.abs(x - nearest) < PIXEL_EPSILON) return nearest;
|
|
910
|
+
return Math.floor(x);
|
|
911
|
+
}
|
|
912
|
+
function pixelCeil(x) {
|
|
913
|
+
const nearest = Math.round(x);
|
|
914
|
+
if (Math.abs(x - nearest) < PIXEL_EPSILON) return nearest;
|
|
915
|
+
return Math.ceil(x);
|
|
916
|
+
}
|
|
917
|
+
function createRegions(options) {
|
|
918
|
+
const scaleX = options.toWidth / options.width;
|
|
919
|
+
const scaleY = options.toHeight / options.height;
|
|
920
|
+
const innerTileWidth = pixelFloor(options.srcTileSize * scaleX) - 2 * options.destTileBorder;
|
|
921
|
+
const innerTileHeight = pixelFloor(options.srcTileSize * scaleY) - 2 * options.destTileBorder;
|
|
922
|
+
if (innerTileWidth < 1 || innerTileHeight < 1) throw new Error("Internal error in pica: target tile width/height is too small.");
|
|
923
|
+
let x, y;
|
|
924
|
+
let innerX, innerY, toTileWidth, toTileHeight;
|
|
925
|
+
const tiles = [];
|
|
926
|
+
let tile;
|
|
927
|
+
for (innerY = 0; innerY < options.toHeight; innerY += innerTileHeight) for (innerX = 0; innerX < options.toWidth; innerX += innerTileWidth) {
|
|
928
|
+
x = innerX - options.destTileBorder;
|
|
929
|
+
if (x < 0) x = 0;
|
|
930
|
+
toTileWidth = innerX + innerTileWidth + options.destTileBorder - x;
|
|
931
|
+
if (x + toTileWidth >= options.toWidth) toTileWidth = options.toWidth - x;
|
|
932
|
+
y = innerY - options.destTileBorder;
|
|
933
|
+
if (y < 0) y = 0;
|
|
934
|
+
toTileHeight = innerY + innerTileHeight + options.destTileBorder - y;
|
|
935
|
+
if (y + toTileHeight >= options.toHeight) toTileHeight = options.toHeight - y;
|
|
936
|
+
tile = {
|
|
937
|
+
toX: x,
|
|
938
|
+
toY: y,
|
|
939
|
+
toWidth: toTileWidth,
|
|
940
|
+
toHeight: toTileHeight,
|
|
941
|
+
toInnerX: innerX,
|
|
942
|
+
toInnerY: innerY,
|
|
943
|
+
toInnerWidth: innerTileWidth,
|
|
944
|
+
toInnerHeight: innerTileHeight,
|
|
945
|
+
offsetX: x / scaleX - pixelFloor(x / scaleX),
|
|
946
|
+
offsetY: y / scaleY - pixelFloor(y / scaleY),
|
|
947
|
+
scaleX,
|
|
948
|
+
scaleY,
|
|
949
|
+
x: pixelFloor(x / scaleX),
|
|
950
|
+
y: pixelFloor(y / scaleY),
|
|
951
|
+
width: pixelCeil(toTileWidth / scaleX),
|
|
952
|
+
height: pixelCeil(toTileHeight / scaleY)
|
|
953
|
+
};
|
|
954
|
+
tiles.push(tile);
|
|
955
|
+
}
|
|
956
|
+
return tiles;
|
|
957
|
+
}
|
|
958
|
+
var ORIENTED_JPEG_BASE64 = "/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/4AAQskZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/wAALCAACAAMBAREA/8QAFAABAAAAAAAAAAAAAAAAAAAACf/EABsQAAMBAQADAAAAAAAAAAAAAAECAwQFABEx/9oACAEBAAA/AC06fW6va0ps7PT179E88MiV02arrCEkjGQZiSEnKc5ovxURVHoADz//2Q==";
|
|
959
|
+
var features = {
|
|
960
|
+
canvas: false,
|
|
961
|
+
offscreen_canvas: false,
|
|
962
|
+
may_be_worker: false,
|
|
963
|
+
create_image_bitmap: false,
|
|
964
|
+
safari_put_image_data_fix: false,
|
|
965
|
+
bug_canvas_orientation_region: true,
|
|
966
|
+
bug_image_bitmap_orientation_region: true,
|
|
967
|
+
cib_resize: false
|
|
968
|
+
};
|
|
969
|
+
var checked = false;
|
|
970
|
+
var checking = null;
|
|
971
|
+
function check_canvas() {
|
|
972
|
+
if (typeof document === "undefined" || !document.createElement) return false;
|
|
973
|
+
try {
|
|
974
|
+
const canvas = document.createElement("canvas");
|
|
975
|
+
canvas.width = 2;
|
|
976
|
+
canvas.height = 1;
|
|
977
|
+
const ctx = canvas.getContext("2d");
|
|
978
|
+
let d = ctx.createImageData(2, 1);
|
|
979
|
+
d.data[0] = 12;
|
|
980
|
+
d.data[1] = 23;
|
|
981
|
+
d.data[2] = 34;
|
|
982
|
+
d.data[3] = 255;
|
|
983
|
+
d.data[4] = 45;
|
|
984
|
+
d.data[5] = 56;
|
|
985
|
+
d.data[6] = 67;
|
|
986
|
+
d.data[7] = 255;
|
|
987
|
+
ctx.putImageData(d, 0, 0);
|
|
988
|
+
d = ctx.getImageData(0, 0, 2, 1);
|
|
989
|
+
return d.data[0] === 12 && d.data[1] === 23 && d.data[2] === 34 && d.data[3] === 255 && d.data[4] === 45 && d.data[5] === 56 && d.data[6] === 67 && d.data[7] === 255;
|
|
990
|
+
} catch (__) {
|
|
1721
991
|
return false;
|
|
1722
992
|
}
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
993
|
+
}
|
|
994
|
+
function check_offscreen_canvas() {
|
|
995
|
+
if (typeof OffscreenCanvas === "undefined") return false;
|
|
996
|
+
try {
|
|
997
|
+
const ctx = new OffscreenCanvas(2, 1).getContext("2d");
|
|
998
|
+
let d = ctx.createImageData(2, 1);
|
|
999
|
+
d.data[0] = 12;
|
|
1000
|
+
d.data[1] = 23;
|
|
1001
|
+
d.data[2] = 34;
|
|
1002
|
+
d.data[3] = 255;
|
|
1003
|
+
d.data[4] = 45;
|
|
1004
|
+
d.data[5] = 56;
|
|
1005
|
+
d.data[6] = 67;
|
|
1006
|
+
d.data[7] = 255;
|
|
1007
|
+
ctx.putImageData(d, 0, 0);
|
|
1008
|
+
d = ctx.getImageData(0, 0, 2, 1);
|
|
1009
|
+
return d.data[0] === 12 && d.data[1] === 23 && d.data[2] === 34 && d.data[3] === 255 && d.data[4] === 45 && d.data[5] === 56 && d.data[6] === 67 && d.data[7] === 255;
|
|
1010
|
+
} catch (__) {
|
|
1011
|
+
return false;
|
|
1728
1012
|
}
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1013
|
+
}
|
|
1014
|
+
function check_create_image_bitmap() {
|
|
1015
|
+
return typeof createImageBitmap !== "undefined";
|
|
1016
|
+
}
|
|
1017
|
+
function check_may_be_worker() {
|
|
1018
|
+
return typeof Worker !== "undefined" && typeof URL !== "undefined" && !!URL.createObjectURL;
|
|
1019
|
+
}
|
|
1020
|
+
function check_safari_put_image_data_fix() {
|
|
1021
|
+
try {
|
|
1022
|
+
return !!(typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.indexOf("Safari") >= 0 && navigator.userAgent.indexOf("Chrome") < 0);
|
|
1023
|
+
} catch (__) {
|
|
1733
1024
|
return false;
|
|
1734
1025
|
}
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1026
|
+
}
|
|
1027
|
+
function check_bug_canvas_orientation_region_async() {
|
|
1028
|
+
return Promise.resolve().then(() => {
|
|
1029
|
+
if (check_offscreen_canvas() && check_create_image_bitmap() && typeof Blob !== "undefined" && typeof atob !== "undefined") {
|
|
1030
|
+
const binary = atob(ORIENTED_JPEG_BASE64);
|
|
1031
|
+
const bytes = new Uint8Array(binary.length);
|
|
1032
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
1033
|
+
return createImageBitmap(new Blob([bytes], { type: "image/jpeg" })).then((bitmap) => {
|
|
1034
|
+
const canvas = new OffscreenCanvas(1, 1);
|
|
1035
|
+
try {
|
|
1036
|
+
const ctx = canvas.getContext("2d");
|
|
1037
|
+
ctx.drawImage(bitmap, 1, 1, 1, 1, 0, 0, 1, 1);
|
|
1038
|
+
return ctx.getImageData(0, 0, 1, 1).data[0] < 240;
|
|
1039
|
+
} finally {
|
|
1040
|
+
bitmap.close();
|
|
1041
|
+
}
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
1044
|
+
if (check_canvas() && typeof Image !== "undefined") return new Promise((resolve) => {
|
|
1045
|
+
const image = new Image();
|
|
1046
|
+
image.onload = () => {
|
|
1047
|
+
try {
|
|
1048
|
+
const canvas = document.createElement("canvas");
|
|
1049
|
+
canvas.width = 1;
|
|
1050
|
+
canvas.height = 1;
|
|
1051
|
+
const ctx = canvas.getContext("2d");
|
|
1052
|
+
ctx.drawImage(image, 1, 1, 1, 1, 0, 0, 1, 1);
|
|
1053
|
+
resolve(ctx.getImageData(0, 0, 1, 1).data[0] < 240);
|
|
1054
|
+
} catch (__) {
|
|
1055
|
+
resolve(true);
|
|
1056
|
+
}
|
|
1057
|
+
};
|
|
1058
|
+
image.onerror = () => resolve(true);
|
|
1059
|
+
image.src = `data:image/jpeg;base64,${ORIENTED_JPEG_BASE64}`;
|
|
1060
|
+
});
|
|
1061
|
+
return true;
|
|
1062
|
+
}).catch(() => true);
|
|
1063
|
+
}
|
|
1064
|
+
function check_bug_image_bitmap_orientation_region_async() {
|
|
1065
|
+
return Promise.resolve().then(() => {
|
|
1066
|
+
if (!features.create_image_bitmap && !check_create_image_bitmap()) return true;
|
|
1067
|
+
if (typeof Blob === "undefined" || typeof atob === "undefined") return true;
|
|
1068
|
+
const canOffscreenCanvas = check_offscreen_canvas();
|
|
1069
|
+
const canCanvas = check_canvas();
|
|
1070
|
+
if (!canOffscreenCanvas && !canCanvas) return true;
|
|
1071
|
+
const binary = atob(ORIENTED_JPEG_BASE64);
|
|
1072
|
+
const bytes = new Uint8Array(binary.length);
|
|
1073
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
1074
|
+
return createImageBitmap(new Blob([bytes], { type: "image/jpeg" })).then((imageBitmap) => createImageBitmap(imageBitmap, 1, 1, 1, 1).then((bitmap) => {
|
|
1075
|
+
let canvas;
|
|
1076
|
+
if (canOffscreenCanvas) canvas = new OffscreenCanvas(1, 1);
|
|
1077
|
+
else {
|
|
1078
|
+
canvas = document.createElement("canvas");
|
|
1079
|
+
canvas.width = 1;
|
|
1080
|
+
canvas.height = 1;
|
|
1081
|
+
}
|
|
1082
|
+
try {
|
|
1083
|
+
const ctx = canvas.getContext("2d");
|
|
1084
|
+
ctx.drawImage(bitmap, 0, 0);
|
|
1085
|
+
return bitmap.width !== 1 || bitmap.height !== 1 || ctx.getImageData(0, 0, 1, 1).data[0] < 240;
|
|
1086
|
+
} finally {
|
|
1087
|
+
imageBitmap.close();
|
|
1088
|
+
bitmap.close();
|
|
1089
|
+
}
|
|
1090
|
+
}, () => {
|
|
1091
|
+
imageBitmap.close();
|
|
1092
|
+
return true;
|
|
1093
|
+
}));
|
|
1094
|
+
}).catch(() => true);
|
|
1095
|
+
}
|
|
1096
|
+
function check_cib_resize_async() {
|
|
1097
|
+
return Promise.resolve().then(() => {
|
|
1098
|
+
if (!check_create_image_bitmap()) return false;
|
|
1099
|
+
const SRC_SIZE = 20;
|
|
1100
|
+
const DST_SIZE = 5;
|
|
1101
|
+
let canvas;
|
|
1102
|
+
if (features.canvas || check_canvas()) {
|
|
1103
|
+
canvas = document.createElement("canvas");
|
|
1104
|
+
canvas.width = SRC_SIZE;
|
|
1105
|
+
canvas.height = SRC_SIZE;
|
|
1106
|
+
} else if (features.offscreen_canvas || check_offscreen_canvas()) {
|
|
1107
|
+
canvas = new OffscreenCanvas(SRC_SIZE, SRC_SIZE);
|
|
1108
|
+
canvas.getContext("2d").clearRect(0, 0, SRC_SIZE, SRC_SIZE);
|
|
1109
|
+
} else return false;
|
|
1110
|
+
return createImageBitmap(canvas, 0, 0, SRC_SIZE, SRC_SIZE, {
|
|
1111
|
+
resizeWidth: DST_SIZE,
|
|
1112
|
+
resizeHeight: DST_SIZE,
|
|
1113
|
+
resizeQuality: "high"
|
|
1114
|
+
}).then((bitmap) => {
|
|
1115
|
+
const status = bitmap.width === DST_SIZE && !!bitmap.close;
|
|
1116
|
+
if (bitmap.close) bitmap.close();
|
|
1117
|
+
canvas = null;
|
|
1118
|
+
return status;
|
|
1119
|
+
});
|
|
1120
|
+
}).catch(() => false);
|
|
1121
|
+
}
|
|
1122
|
+
function get_supported_features() {
|
|
1123
|
+
if (checked) return Promise.resolve(Object.assign({}, features));
|
|
1124
|
+
if (checking) return checking.then(() => Object.assign({}, features));
|
|
1125
|
+
features.canvas = check_canvas();
|
|
1126
|
+
features.offscreen_canvas = check_offscreen_canvas();
|
|
1127
|
+
features.may_be_worker = check_may_be_worker();
|
|
1128
|
+
features.create_image_bitmap = check_create_image_bitmap();
|
|
1129
|
+
features.safari_put_image_data_fix = check_safari_put_image_data_fix();
|
|
1130
|
+
const bugCanvasOrientationRegion = check_bug_canvas_orientation_region_async().then((result) => {
|
|
1131
|
+
features.bug_canvas_orientation_region = result;
|
|
1132
|
+
}).catch(() => {});
|
|
1133
|
+
const bugImageBitmapOrientationRegion = check_bug_image_bitmap_orientation_region_async().then((result) => {
|
|
1134
|
+
features.bug_image_bitmap_orientation_region = result;
|
|
1135
|
+
}).catch(() => {});
|
|
1136
|
+
const cibResize = check_cib_resize_async().then((result) => {
|
|
1137
|
+
features.cib_resize = result;
|
|
1138
|
+
}).catch(() => {});
|
|
1139
|
+
checking = Promise.all([
|
|
1140
|
+
bugCanvasOrientationRegion,
|
|
1141
|
+
bugImageBitmapOrientationRegion,
|
|
1142
|
+
cibResize
|
|
1143
|
+
]).then(() => {
|
|
1144
|
+
checked = true;
|
|
1145
|
+
checking = null;
|
|
1146
|
+
return Object.assign({}, features);
|
|
1147
|
+
}, (err) => {
|
|
1148
|
+
checking = null;
|
|
1149
|
+
throw err;
|
|
1740
1150
|
});
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1151
|
+
return checking;
|
|
1152
|
+
}
|
|
1153
|
+
function asyncGeneratorStep(n, t, e, r, o, a, c) {
|
|
1154
|
+
try {
|
|
1155
|
+
var i = n[a](c), u = i.value;
|
|
1156
|
+
} catch (n) {
|
|
1157
|
+
e(n);
|
|
1158
|
+
return;
|
|
1744
1159
|
}
|
|
1745
|
-
|
|
1746
|
-
return true;
|
|
1747
|
-
} catch (err) {
|
|
1748
|
-
// We don't expect any of the above to throw, but better to be safe.
|
|
1749
|
-
return false;
|
|
1160
|
+
i.done ? t(u) : Promise.resolve(u).then(r, o);
|
|
1750
1161
|
}
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1162
|
+
function _asyncToGenerator(n) {
|
|
1163
|
+
return function() {
|
|
1164
|
+
var t = this, e = arguments;
|
|
1165
|
+
return new Promise(function(r, o) {
|
|
1166
|
+
var a = n.apply(t, e);
|
|
1167
|
+
function _next(n) {
|
|
1168
|
+
asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
|
|
1169
|
+
}
|
|
1170
|
+
function _throw(n) {
|
|
1171
|
+
asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
|
|
1172
|
+
}
|
|
1173
|
+
_next(void 0);
|
|
1174
|
+
});
|
|
1175
|
+
};
|
|
1176
|
+
}
|
|
1177
|
+
var WORKER_SRC = "/*!\n\npica\nhttps://github.com/nodeca/pica\n\n*/\n!function(){var A;function t(A){const t=A.replace(/[\\r\\n=]/g,\"\"),e=t.length,n=new Uint8Array(3*e>>2);let a=0,i=0;for(let s=0;s<e;s++)s%4==0&&s&&(n[i++]=a>>16&255,n[i++]=a>>8&255,n[i++]=255&a),a=a<<6|\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\".indexOf(t.charAt(s));const r=e%4*6;return 0===r?(n[i++]=a>>16&255,n[i++]=a>>8&255,n[i++]=255&a):18===r?(n[i++]=a>>10&255,n[i++]=a>>2&255):12===r&&(n[i++]=a>>4&255),n}var e={js:!0,wasm:!0},n=class{constructor(A){const t=Object.assign({},e,A||{});if(this.options=t,this.__cache={},this.__init_promise=null,this.__modules=t.modules||{},this.__memory=null,this.__wasm={},this.__isLE=1===new Uint32Array(new Uint8Array([1,0,0,0]).buffer)[0],!this.options.js&&!this.options.wasm)throw new Error('mathlib: at least \"js\" or \"wasm\" should be enabled')}has_wasm(){return function(){if(void 0!==A)return A;if(A=!1,\"undefined\"==typeof WebAssembly)return A;try{const t=new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,127,3,2,1,0,5,3,1,0,1,7,8,1,4,116,101,115,116,0,0,10,16,1,14,0,32,0,65,1,54,2,0,32,0,40,2,0,11]),e=new WebAssembly.Module(t);return 0!==new WebAssembly.Instance(e,{}).exports.test(4)&&(A=!0),A}catch(t){}return A}()}use(A){return this.__modules[A.name]=A,this.options.wasm&&this.has_wasm()&&A.wasm_fn?this[A.name]=A.wasm_fn:this[A.name]=A.fn,this}init(){return this.__init_promise?this.__init_promise:this.options.js||!this.options.wasm||this.has_wasm()?(this.__init_promise=Promise.all(Object.keys(this.__modules).map(A=>{const e=this.__modules[A];return this.options.wasm&&this.has_wasm()&&e.wasm_fn?this.__wasm[A]?null:WebAssembly.compile(t(e.wasm_src)).then(t=>{this.__wasm[A]=t}):null})).then(()=>this),this.__init_promise):Promise.reject(new Error('mathlib: only \"wasm\" was enabled, but it\\'s not supported'))}__reallocate(A){if(!this.__memory)return this.__memory=new WebAssembly.Memory({initial:Math.ceil(A/65536)}),this.__memory;const t=this.__memory.buffer.byteLength;return t<A&&this.__memory.grow(Math.ceil((A-t)/65536)),this.__memory}__instance(A,e,n){if(e&&this.__reallocate(e),!this.__wasm[A]){const e=this.__modules[A];this.__wasm[A]=new WebAssembly.Module(t(e.wasm_src))}if(!this.__cache[A]){const t={memoryBase:0,memory:this.__memory,tableBase:0,table:new WebAssembly.Table({initial:0,element:\"anyfunc\"})};this.__cache[A]=new WebAssembly.Instance(this.__wasm[A],{env:Object.assign(t,n||{})})}return this.__cache[A]}__align(A,t){const e=A%(t=t||8);return A+(e?t-e:0)}};function a(A,t,e,n,a,i){let r,s,o,g,I,h,B,Q,E,C,c,f,u,m;for(E=0;E<i;E++){for(h=E*a,B=E,Q=0,r=A[h],I=r*n[6],g=I,c=n[0],f=n[1],u=n[4],m=n[5],C=0;C<a;C++)s=A[h],o=s*c+r*f+g*u+I*m,I=g,g=o,r=s,e[Q]=g,Q++,h++;for(h--,Q--,B+=i*(a-1),r=A[h],I=r*n[7],g=I,s=r,c=n[2],f=n[3],C=a-1;C>=0;C--)o=s*c+r*f+g*u+I*m,I=g,g=o,r=s,s=A[h],t[B]=e[Q]+g,h--,Q--,B-=i}}function i(A,t,e,n){if(!n)return;const i=new Uint16Array(A.length),r=new Float32Array(Math.max(t,e)),s=function(A){A<.5&&(A=.5);const t=Math.exp(.527076)/A,e=Math.exp(-t),n=Math.exp(-2*t),a=(1-e)*(1-e)/(1+2*t*e-n),i=a*(t-1)*e,r=a*(t+1)*e,s=-a*n,o=2*e,g=-n;return new Float32Array([a,i,r,s,o,g,(a+i)/(1-o-g),(r+s)/(1-o-g)])}(n);a(A,i,r,s,t,e),a(i,A,r,s,e,t)}var r={name:\"unsharp_mask\",fn:function(A,t,e,n,a,r){let s,o,g,I,h;if(0===n||a<.5)return;a>2&&(a=2);const B=function(A,t,e){const n=t*e,a=new Uint16Array(n);let i,r,s,o;for(let g=0;g<n;g++)i=A[4*g],r=A[4*g+1],s=A[4*g+2],o=i>=r&&i>=s?i:r>=s&&r>=i?r:s,a[g]=o<<8;return a}(A,t,e),Q=new Uint16Array(B);i(Q,t,e,a);const E=n/100*4096+.5|0,C=r<<8,c=t*e;for(let i=0;i<c;i++)s=B[i],I=s-Q[i],Math.abs(I)>=C&&(o=s+(E*I+2048>>12),o=o>65280?65280:o,o=o<0?0:o,s=0!==s?s:1,g=(o<<12)/s|0,h=4*i,A[h]=A[h]*g+2048>>12,A[h+1]=A[h+1]*g+2048>>12,A[h+2]=A[h+2]*g+2048>>12)},wasm_fn:function(A,t,e,n,a,i){if(0===n||a<.5)return;a>2&&(a=2);const r=t*e,s=4*r,o=2*r,g=2*r,I=4*Math.max(t,e),h=s,B=h+o,Q=B+g,E=Q+g,C=E+I,c=this.__instance(\"unsharp_mask\",s+o+2*g+I+32,{exp:Math.exp}),f=new Uint32Array(A.buffer);new Uint32Array(this.__memory.buffer).set(f);let u=c.exports.hsv_v16||c.exports._hsv_v16;if(!u)throw new Error(\"WASM hsv_v16 function is not available\");if(u(0,h,t,e),u=c.exports.blurMono16||c.exports._blurMono16,!u)throw new Error(\"WASM blurMono16 function is not available\");if(u(h,B,Q,E,C,t,e,a),u=c.exports.unsharp||c.exports._unsharp,!u)throw new Error(\"WASM unsharp function is not available\");u(0,0,h,B,t,e,n,i),f.set(new Uint32Array(this.__memory.buffer,0,r))},wasm_src:\"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\"},s={filter:{box:{win:.5,fn:A=>(A<0&&(A=-A),A<.5?1:0)},hamming:{win:1,fn(A){if(A<0&&(A=-A),A>=1)return 0;if(A<1.1920929e-7)return 1;const t=A*Math.PI;return Math.sin(t)/t*(.54+.46*Math.cos(t/1))}},lanczos2:{win:2,fn(A){if(A<0&&(A=-A),A>=2)return 0;if(A<1.1920929e-7)return 1;const t=A*Math.PI;return Math.sin(t)/t*Math.sin(t/2)/(t/2)}},lanczos3:{win:3,fn(A){if(A<0&&(A=-A),A>=3)return 0;if(A<1.1920929e-7)return 1;const t=A*Math.PI;return Math.sin(t)/t*Math.sin(t/3)/(t/3)}},mks2013:{win:2.5,fn:A=>(A<0&&(A=-A),A>=2.5?0:A>=1.5?-.125*(A-2.5)*(A-2.5):A>=.5?.25*(4*A*A-11*A+7):1.0625-1.75*A*A)}}};function o(A){return Math.round(16383*A)}function g(A,t,e,n,a){const i=s.filter[A].fn,r=1/n,g=Math.min(1,n),I=s.filter[A].win/g;let h,B,Q,E,C,c,f,u,m,d,w,l,y,_,b,D,M;const p=Math.floor(2*(I+1)),G=new Int16Array((p+2)*e);let U=0;const k=!G.subarray||!G.set;for(h=0;h<e;h++){for(B=(h+.5)*r+a,Q=Math.max(0,Math.floor(B-I)),E=Math.min(t-1,Math.ceil(B+I)),C=E-Q+1,c=new Float32Array(C),f=new Int16Array(C),u=0,m=Q,d=0;m<=E;m++,d++)w=i((m+.5-B)*g),u+=w,c[d]=w;for(l=0,d=0;d<c.length;d++)y=c[d]/u,l+=y,f[d]=o(y);for(f[e>>1]+=o(1-l),_=0;_<f.length&&0===f[_];)_++;if(_<f.length){for(b=f.length-1;b>0&&0===f[b];)b--;if(D=Q+_,M=b-_+1,G[U++]=D,G[U++]=M,k)for(d=_;d<=b;d++)G[U++]=f[d];else G.set(f.subarray(_,b+1),U),U+=M}else G[U++]=0,G[U++]=0}return G}function I(A){return A<0?0:A>255?255:A}function h(A){return A>=0?A:0}var B=!0;try{B=1===new Uint32Array(new Uint8Array([1,0,0,0]).buffer)[0]}catch(p){}function Q(A,t,e){if(B)t.set(function(A){return new Uint8Array(A.buffer,0,A.byteLength)}(A),e);else for(let n=e,a=0;a<A.length;a++){const e=A[a];t[n++]=255&e,t[n++]=e>>8&255}}var E={name:\"resize\",fn:function(A){const t=A.src,e=A.width,n=A.height,a=A.toWidth,i=A.toHeight,r=A.scaleX||A.toWidth/A.width,s=A.scaleY||A.toHeight/A.height,o=A.offsetX||0,B=A.offsetY||0,Q=A.dest||new Uint8Array(a*i*4),E=void 0===A.filter?\"mks2013\":A.filter,C=g(E,e,a,r,o),c=g(E,n,i,s,B),f=new Uint16Array(a*n*4);return!function(A,t,e){let n=3;const a=t*e*4|0;for(;n<a;){if(255!==A[n])return!0;n=n+4|0}return!1}(t,e,n)?(function(A,t,e,n,a,i){let r,s,o,g,I,B,Q,E,C,c,f,u=0,m=0;for(C=0;C<n;C++){for(I=0,c=0;c<a;c++){for(B=i[I++],Q=i[I++],E=u+4*B|0,r=s=o=g=0;Q>0;Q--)f=i[I++],g=g+f*A[E+3]|0,o=o+f*A[E+2]|0,s=s+f*A[E+1]|0,r=r+f*A[E]|0,E=E+4|0;t[m+3]=h(g>>7),t[m+2]=h(o>>7),t[m+1]=h(s>>7),t[m]=h(r>>7),m=m+4*n|0}m=4*(C+1)|0,u=(C+1)*e*4|0}}(t,f,e,n,a,C),function(A,t,e,n,a,i){let r,s,o,g,h,B,Q,E,C,c,f,u=0,m=0;for(C=0;C<n;C++){for(h=0,c=0;c<a;c++){for(B=i[h++],Q=i[h++],E=u+4*B|0,r=s=o=g=0;Q>0;Q--)f=i[h++],g=g+f*A[E+3]|0,o=o+f*A[E+2]|0,s=s+f*A[E+1]|0,r=r+f*A[E]|0,E=E+4|0;r>>=7,s>>=7,o>>=7,g>>=7,t[m+3]=I(g+8192>>14),t[m+2]=I(o+8192>>14),t[m+1]=I(s+8192>>14),t[m]=I(r+8192>>14),m=m+4*n|0}m=4*(C+1)|0,u=(C+1)*e*4|0}}(f,Q,n,a,i,c),function(A,t,e){let n=3;const a=t*e*4|0;for(;n<a;)A[n]=255,n=n+4|0}(Q,a,i)):(function(A,t,e,n,a,i){let r,s,o,g,I,B,Q,E,C,c,f,u,m=0,d=0;for(c=0;c<n;c++){for(B=0,f=0;f<a;f++){for(Q=i[B++],E=i[B++],C=m+4*Q|0,r=s=o=g=0;E>0;E--)u=i[B++],I=A[C+3],g=g+u*I|0,o=o+u*A[C+2]*I|0,s=s+u*A[C+1]*I|0,r=r+u*A[C]*I|0,C=C+4|0;o=o/255|0,s=s/255|0,r=r/255|0,t[d+3]=h(g>>7),t[d+2]=h(o>>7),t[d+1]=h(s>>7),t[d]=h(r>>7),d=d+4*n|0}d=4*(c+1)|0,m=(c+1)*e*4|0}}(t,f,e,n,a,C),function(A,t,e,n,a,i){let r,s,o,g,h,B,Q,E,C,c,f,u=0,m=0;for(C=0;C<n;C++){for(h=0,c=0;c<a;c++){for(B=i[h++],Q=i[h++],E=u+4*B|0,r=s=o=g=0;Q>0;Q--)f=i[h++],g=g+f*A[E+3]|0,o=o+f*A[E+2]|0,s=s+f*A[E+1]|0,r=r+f*A[E]|0,E=E+4|0;r>>=7,s>>=7,o>>=7,g>>=7,g=I(g+8192>>14),g>0&&(r=255*r/g|0,s=255*s/g|0,o=255*o/g|0),t[m+3]=g,t[m+2]=I(o+8192>>14),t[m+1]=I(s+8192>>14),t[m]=I(r+8192>>14),m=m+4*n|0}m=4*(C+1)|0,u=(C+1)*e*4|0}}(f,Q,n,a,i,c)),Q},wasm_fn:function(A){const t=A.src,e=A.width,n=A.height,a=A.toWidth,i=A.toHeight,r=A.scaleX||A.toWidth/A.width,s=A.scaleY||A.toHeight/A.height,o=A.offsetX||0,I=A.offsetY||0,h=A.dest||new Uint8Array(a*i*4),B=void 0===A.filter?\"mks2013\":A.filter,E=g(B,e,a,r,o),C=g(B,n,i,s,I),c=Math.max(t.byteLength,h.byteLength),f=this.__align(0+c),u=n*a*4*2,m=this.__align(f+u),d=this.__align(m+E.byteLength),w=d+C.byteLength,l=this.__instance(\"resize\",w),y=new Uint8Array(this.__memory.buffer),_=new Uint32Array(this.__memory.buffer),b=new Uint32Array(t.buffer);_.set(b),Q(E,y,m),Q(C,y,d);const D=l.exports.convolveHV||l.exports._convolveHV;if(!D)throw new Error(\"WASM resize function is not available\");return!function(A,t,e){let n=3;const a=t*e*4|0;for(;n<a;){if(255!==A[n])return!0;n=n+4|0}return!1}(t,e,n)?(D(m,d,f,e,n,a,i,0),function(A,t,e){let n=3;const a=t*e*4|0;for(;n<a;)A[n]=255,n=n+4|0}(h,a,i)):D(m,d,f,e,n,a,i,1),new Uint32Array(h.buffer).set(new Uint32Array(this.__memory.buffer,0,i*a)),h},wasm_src:\"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\"},C=class extends n{constructor(A){const t=A||[],e={js:t.indexOf(\"js\")>=0,wasm:t.indexOf(\"wasm\")>=0};super(e),this.features={js:e.js,wasm:e.wasm&&this.has_wasm()},this.use(r),this.use(E)}resizeAndUnsharp(A){const t=this.resize(A);return A.unsharpAmount&&this.unsharp_mask(t,A.toWidth,A.toHeight,A.unsharpAmount,A.unsharpRadius,A.unsharpThreshold),t}},c=\"/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/4AAQskZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/wAALCAACAAMBAREA/8QAFAABAAAAAAAAAAAAAAAAAAAACf/EABsQAAMBAQADAAAAAAAAAAAAAAECAwQFABEx/9oACAEBAAA/AC06fW6va0ps7PT179E88MiV02arrCEkjGQZiSEnKc5ovxURVHoADz//2Q==\",f={canvas:!1,offscreen_canvas:!1,may_be_worker:!1,create_image_bitmap:!1,safari_put_image_data_fix:!1,bug_canvas_orientation_region:!0,bug_image_bitmap_orientation_region:!0,cib_resize:!1},u=!1,m=null;function d(){if(\"undefined\"==typeof document||!document.createElement)return!1;try{const A=document.createElement(\"canvas\");A.width=2,A.height=1;const t=A.getContext(\"2d\");let e=t.createImageData(2,1);return e.data[0]=12,e.data[1]=23,e.data[2]=34,e.data[3]=255,e.data[4]=45,e.data[5]=56,e.data[6]=67,e.data[7]=255,t.putImageData(e,0,0),e=t.getImageData(0,0,2,1),12===e.data[0]&&23===e.data[1]&&34===e.data[2]&&255===e.data[3]&&45===e.data[4]&&56===e.data[5]&&67===e.data[6]&&255===e.data[7]}catch(p){return!1}}function w(){if(\"undefined\"==typeof OffscreenCanvas)return!1;try{const A=new OffscreenCanvas(2,1).getContext(\"2d\");let t=A.createImageData(2,1);return t.data[0]=12,t.data[1]=23,t.data[2]=34,t.data[3]=255,t.data[4]=45,t.data[5]=56,t.data[6]=67,t.data[7]=255,A.putImageData(t,0,0),t=A.getImageData(0,0,2,1),12===t.data[0]&&23===t.data[1]&&34===t.data[2]&&255===t.data[3]&&45===t.data[4]&&56===t.data[5]&&67===t.data[6]&&255===t.data[7]}catch(p){return!1}}function l(){return\"undefined\"!=typeof createImageBitmap}function y(){if(u)return Promise.resolve(Object.assign({},f));if(m)return m.then(()=>Object.assign({},f));f.canvas=d(),f.offscreen_canvas=w(),f.may_be_worker=\"undefined\"!=typeof Worker&&\"undefined\"!=typeof URL&&!!URL.createObjectURL,f.create_image_bitmap=l(),f.safari_put_image_data_fix=function(){try{return!!(\"undefined\"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.indexOf(\"Safari\")>=0&&navigator.userAgent.indexOf(\"Chrome\")<0)}catch(p){return!1}}();const A=Promise.resolve().then(()=>{if(w()&&l()&&\"undefined\"!=typeof Blob&&\"undefined\"!=typeof atob){const A=atob(c),t=new Uint8Array(A.length);for(let e=0;e<A.length;e++)t[e]=A.charCodeAt(e);return createImageBitmap(new Blob([t],{type:\"image/jpeg\"})).then(A=>{const t=new OffscreenCanvas(1,1);try{const e=t.getContext(\"2d\");return e.drawImage(A,1,1,1,1,0,0,1,1),e.getImageData(0,0,1,1).data[0]<240}finally{A.close()}})}return!d()||\"undefined\"==typeof Image||new Promise(A=>{const t=new Image;t.onload=()=>{try{const e=document.createElement(\"canvas\");e.width=1,e.height=1;const n=e.getContext(\"2d\");n.drawImage(t,1,1,1,1,0,0,1,1),A(n.getImageData(0,0,1,1).data[0]<240)}catch(p){A(!0)}},t.onerror=()=>A(!0),t.src=`data:image/jpeg;base64,${c}`})}).catch(()=>!0).then(A=>{f.bug_canvas_orientation_region=A}).catch(()=>{}),t=Promise.resolve().then(()=>{if(!f.create_image_bitmap&&!l())return!0;if(\"undefined\"==typeof Blob||\"undefined\"==typeof atob)return!0;const A=w(),t=d();if(!A&&!t)return!0;const e=atob(c),n=new Uint8Array(e.length);for(let a=0;a<e.length;a++)n[a]=e.charCodeAt(a);return createImageBitmap(new Blob([n],{type:\"image/jpeg\"})).then(t=>createImageBitmap(t,1,1,1,1).then(e=>{let n;A?n=new OffscreenCanvas(1,1):(n=document.createElement(\"canvas\"),n.width=1,n.height=1);try{const A=n.getContext(\"2d\");return A.drawImage(e,0,0),1!==e.width||1!==e.height||A.getImageData(0,0,1,1).data[0]<240}finally{t.close(),e.close()}},()=>(t.close(),!0)))}).catch(()=>!0).then(A=>{f.bug_image_bitmap_orientation_region=A}).catch(()=>{}),e=Promise.resolve().then(()=>{if(!l())return!1;const A=20;let t;if(f.canvas||d())t=document.createElement(\"canvas\"),t.width=A,t.height=A;else{if(!f.offscreen_canvas&&!w())return!1;t=new OffscreenCanvas(A,A),t.getContext(\"2d\").clearRect(0,0,A,A)}return createImageBitmap(t,0,0,A,A,{resizeWidth:5,resizeHeight:5,resizeQuality:\"high\"}).then(A=>{const e=5===A.width&&!!A.close;return A.close&&A.close(),t=null,e})}).catch(()=>!1).then(A=>{f.cib_resize=A}).catch(()=>{});return m=Promise.all([A,t,e]).then(()=>(u=!0,m=null,Object.assign({},f)),A=>{throw m=null,A})}var _=self,b=null;function D(A,t){return b||(b=new C(A.features)),b.resizeAndUnsharp(t)}function M(A){if(\"bitmap\"===A.job.kind)return void function(A,t){let e=new OffscreenCanvas(t.width,t.height);const n=e.getContext(\"2d\");n.drawImage(t.src,0,0);const a=n.getImageData(0,0,t.width,t.height).data;e.width=e.height=0,e=null,t.src.close();const i=D(A,{src:a,width:t.width,height:t.height,toWidth:t.toWidth,toHeight:t.toHeight,scaleX:t.scaleX,scaleY:t.scaleY,offsetX:t.offsetX,offsetY:t.offsetY,filter:t.filter,unsharpAmount:t.unsharpAmount,unsharpRadius:t.unsharpRadius,unsharpThreshold:t.unsharpThreshold}),r=new OffscreenCanvas(t.toWidth,t.toHeight),s=r.getContext(\"2d\"),o=s.createImageData(t.toWidth,t.toHeight);o.data.set(i),s.putImageData(o,0,0);const g=r.transferToImageBitmap();_.postMessage({kind:\"bitmap\",data:g},[g])}(A,A.job);const t=D(A,A.job);_.postMessage({kind:\"array\",data:t},[t.buffer])}_.onmessage=function(A){Promise.resolve().then(()=>function(A){switch(A.method){case\"get_supported_features\":return y().then(A=>{_.postMessage({data:A})});case\"resize\":return M(A),Promise.resolve();default:return Promise.reject(new Error(`Unknown worker method: ${A.method}`))}}(A.data)).catch(A=>{_.postMessage({err:A})})}}();\n//# sourceURL=pica-inline-worker.js";
|
|
1178
|
+
var concurrency = 1;
|
|
1179
|
+
if (typeof navigator !== "undefined") concurrency = Math.min(navigator.hardwareConcurrency || 1, 4);
|
|
1180
|
+
var DEFAULT_PICA_OPTS = {
|
|
1181
|
+
tile: 1024,
|
|
1182
|
+
concurrency,
|
|
1183
|
+
features: [
|
|
1184
|
+
"js",
|
|
1185
|
+
"wasm",
|
|
1186
|
+
"ww"
|
|
1187
|
+
],
|
|
1188
|
+
idle: 2e3
|
|
1189
|
+
};
|
|
1190
|
+
var DEFAULT_RESIZE_OPTS = {
|
|
1191
|
+
filter: "mks2013",
|
|
1192
|
+
unsharpAmount: 0,
|
|
1193
|
+
unsharpRadius: 0,
|
|
1194
|
+
unsharpThreshold: 0
|
|
1195
|
+
};
|
|
1196
|
+
var Pica = class {
|
|
1197
|
+
constructor(options) {
|
|
1198
|
+
_defineProperty(this, "options", void 0);
|
|
1199
|
+
_defineProperty(this, "__limit", void 0);
|
|
1200
|
+
_defineProperty(this, "resize_features", void 0);
|
|
1201
|
+
_defineProperty(this, "__workersPool", void 0);
|
|
1202
|
+
_defineProperty(this, "capabilities", void 0);
|
|
1203
|
+
_defineProperty(this, "__requested_features", void 0);
|
|
1204
|
+
_defineProperty(this, "__mathlib", void 0);
|
|
1205
|
+
_defineProperty(this, "__initPromise", void 0);
|
|
1206
|
+
this.options = Object.assign({}, DEFAULT_PICA_OPTS, options || {});
|
|
1207
|
+
if ((this.options.features.indexOf("ww") >= 0 || this.options.features.indexOf("all") >= 0) && !this.options.workerURL && false);
|
|
1208
|
+
this.__limit = limiter(this.options.concurrency);
|
|
1209
|
+
this.resize_features = {
|
|
1210
|
+
js: false,
|
|
1211
|
+
wasm: false,
|
|
1212
|
+
cib: false,
|
|
1213
|
+
ww: false
|
|
1214
|
+
};
|
|
1215
|
+
this.__workersPool = null;
|
|
1216
|
+
this.capabilities = {
|
|
1217
|
+
worker: false,
|
|
1218
|
+
ww_offscreen_canvas: false,
|
|
1219
|
+
canvas: false,
|
|
1220
|
+
offscreen_canvas: false,
|
|
1221
|
+
may_be_worker: false,
|
|
1222
|
+
create_image_bitmap: false,
|
|
1223
|
+
safari_put_image_data_fix: false,
|
|
1224
|
+
bug_canvas_orientation_region: true,
|
|
1225
|
+
bug_image_bitmap_orientation_region: true,
|
|
1226
|
+
cib_resize: false
|
|
1227
|
+
};
|
|
1228
|
+
this.__requested_features = [];
|
|
1229
|
+
this.__mathlib = null;
|
|
1230
|
+
}
|
|
1231
|
+
init() {
|
|
1232
|
+
if (this.__initPromise) return this.__initPromise;
|
|
1233
|
+
this.__initPromise = this.__init();
|
|
1234
|
+
return this.__initPromise;
|
|
1235
|
+
}
|
|
1236
|
+
__init() {
|
|
1237
|
+
var _this = this;
|
|
1238
|
+
return _asyncToGenerator(function* () {
|
|
1239
|
+
let features = _this.options.features.slice();
|
|
1240
|
+
if (features.indexOf("all") >= 0) features = [
|
|
1241
|
+
"cib",
|
|
1242
|
+
"wasm",
|
|
1243
|
+
"js",
|
|
1244
|
+
"ww"
|
|
1245
|
+
];
|
|
1246
|
+
_this.__requested_features = features;
|
|
1247
|
+
_this.__mathlib = new MathLib(features);
|
|
1248
|
+
const result = yield get_supported_features();
|
|
1249
|
+
Object.assign(_this.capabilities, result);
|
|
1250
|
+
if (_this.capabilities.cib_resize && features.indexOf("cib") >= 0) _this.resize_features.cib = true;
|
|
1251
|
+
if (_this.capabilities.may_be_worker && features.indexOf("ww") >= 0 && WORKER_SRC) _this.__workersPool = new Pool(() => _this.__createWorkerSlot(), _this.options.idle);
|
|
1252
|
+
if (_this.__workersPool) try {
|
|
1253
|
+
const result = yield _this.__invokeWorker("get_supported_features");
|
|
1254
|
+
const resultData = result && result.data;
|
|
1255
|
+
if (resultData) {
|
|
1256
|
+
_this.capabilities.worker = true;
|
|
1257
|
+
_this.resize_features.ww = true;
|
|
1258
|
+
_this.capabilities.ww_offscreen_canvas = !!resultData.offscreen_canvas;
|
|
1259
|
+
}
|
|
1260
|
+
} catch (__) {}
|
|
1261
|
+
const mathlib = yield _this.__mathlib.init();
|
|
1262
|
+
Object.assign(_this.resize_features, mathlib.features);
|
|
1263
|
+
return _this;
|
|
1264
|
+
})();
|
|
1265
|
+
}
|
|
1266
|
+
createCanvas(width, height, preferOffscreen) {
|
|
1267
|
+
if (preferOffscreen && this.capabilities.offscreen_canvas) return new OffscreenCanvas(width, height);
|
|
1268
|
+
if (this.capabilities.canvas) {
|
|
1269
|
+
const canvas = document.createElement("canvas");
|
|
1270
|
+
canvas.width = width;
|
|
1271
|
+
canvas.height = height;
|
|
1272
|
+
return canvas;
|
|
1764
1273
|
}
|
|
1274
|
+
if (this.capabilities.ww_offscreen_canvas) return new OffscreenCanvas(width, height);
|
|
1275
|
+
throw new Error("Pica: cannot create canvas");
|
|
1765
1276
|
}
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1277
|
+
__createWorkerSlot() {
|
|
1278
|
+
if (this.options.workerURL) {
|
|
1279
|
+
const worker = new Worker(String(this.options.workerURL));
|
|
1280
|
+
return {
|
|
1281
|
+
value: worker,
|
|
1282
|
+
destroy() {
|
|
1283
|
+
worker.terminate();
|
|
1284
|
+
}
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1287
|
+
{
|
|
1288
|
+
const objectURL = window.URL.createObjectURL(new Blob([WORKER_SRC], { type: "text/javascript" }));
|
|
1289
|
+
const worker = new Worker(objectURL);
|
|
1290
|
+
return {
|
|
1291
|
+
value: worker,
|
|
1292
|
+
destroy() {
|
|
1293
|
+
worker.terminate();
|
|
1294
|
+
if (typeof window !== "undefined") {
|
|
1295
|
+
var _window$URL, _window$URL$revokeObj;
|
|
1296
|
+
(_window$URL = window.URL) === null || _window$URL === void 0 || (_window$URL$revokeObj = _window$URL.revokeObjectURL) === null || _window$URL$revokeObj === void 0 || _window$URL$revokeObj.call(_window$URL, objectURL);
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
throw new Error("Pica: no worker source available");
|
|
1302
|
+
}
|
|
1303
|
+
__invokeWorker(method, payload, transfer, opts) {
|
|
1304
|
+
return new Promise((resolve, reject) => {
|
|
1305
|
+
const w = this.__workersPool.acquire();
|
|
1306
|
+
if (opts && opts.cancelToken) opts.cancelToken.catch((err) => reject(err));
|
|
1307
|
+
w.value.onmessage = (ev) => {
|
|
1308
|
+
w.release();
|
|
1309
|
+
if (ev.data.err) reject(ev.data.err);
|
|
1310
|
+
else resolve(ev.data);
|
|
1311
|
+
};
|
|
1312
|
+
w.value.postMessage(Object.assign({ method }, payload || {}), transfer || []);
|
|
1313
|
+
});
|
|
1314
|
+
}
|
|
1315
|
+
__invokeResize(tileJob, ctx) {
|
|
1316
|
+
var _this2 = this;
|
|
1317
|
+
return _asyncToGenerator(function* () {
|
|
1318
|
+
yield Promise.resolve();
|
|
1319
|
+
if (!_this2.resize_features.ww) {
|
|
1320
|
+
if (tileJob.kind !== "array") throw new Error("Pica: resize tile data is missing");
|
|
1321
|
+
const mathOpts = {
|
|
1322
|
+
src: tileJob.src,
|
|
1323
|
+
width: tileJob.width,
|
|
1324
|
+
height: tileJob.height,
|
|
1325
|
+
toWidth: tileJob.toWidth,
|
|
1326
|
+
toHeight: tileJob.toHeight,
|
|
1327
|
+
scaleX: tileJob.scaleX,
|
|
1328
|
+
scaleY: tileJob.scaleY,
|
|
1329
|
+
offsetX: tileJob.offsetX,
|
|
1330
|
+
offsetY: tileJob.offsetY,
|
|
1331
|
+
filter: tileJob.filter,
|
|
1332
|
+
unsharpAmount: tileJob.unsharpAmount,
|
|
1333
|
+
unsharpRadius: tileJob.unsharpRadius,
|
|
1334
|
+
unsharpThreshold: tileJob.unsharpThreshold
|
|
1335
|
+
};
|
|
1336
|
+
return {
|
|
1337
|
+
kind: "array",
|
|
1338
|
+
data: _this2.__mathlib.resizeAndUnsharp(mathOpts)
|
|
1339
|
+
};
|
|
1772
1340
|
}
|
|
1341
|
+
const transfer = [];
|
|
1342
|
+
if (tileJob.kind === "array") transfer.push(tileJob.src.buffer);
|
|
1343
|
+
else transfer.push(tileJob.src);
|
|
1344
|
+
return _this2.__invokeWorker("resize", {
|
|
1345
|
+
job: tileJob,
|
|
1346
|
+
features: _this2.__requested_features
|
|
1347
|
+
}, transfer, ctx);
|
|
1348
|
+
})();
|
|
1349
|
+
}
|
|
1350
|
+
__extractTileData(tile, from, stageEnv, extractTo) {
|
|
1351
|
+
if (this.resize_features.ww && this.capabilities.ww_offscreen_canvas) {
|
|
1352
|
+
this.debug("Create tile imageBitmap");
|
|
1353
|
+
const tileCanvas = this.createCanvas(tile.width, tile.height, { preferOffscreen: true });
|
|
1354
|
+
tileCanvas.getContext("2d").drawImage(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height, 0, 0, tile.width, tile.height);
|
|
1355
|
+
if (!("transferToImageBitmap" in tileCanvas)) throw new Error("Pica: offscreen canvas is not available for worker transfer");
|
|
1356
|
+
return Object.assign({}, extractTo, {
|
|
1357
|
+
kind: "bitmap",
|
|
1358
|
+
src: tileCanvas.transferToImageBitmap()
|
|
1359
|
+
});
|
|
1360
|
+
}
|
|
1361
|
+
if (isCanvas(from)) {
|
|
1362
|
+
if (!stageEnv.srcCtx) stageEnv.srcCtx = from.getContext("2d");
|
|
1363
|
+
this.debug("Get tile pixel data");
|
|
1364
|
+
return Object.assign({}, extractTo, {
|
|
1365
|
+
kind: "array",
|
|
1366
|
+
src: stageEnv.srcCtx.getImageData(tile.x, tile.y, tile.width, tile.height).data
|
|
1367
|
+
});
|
|
1773
1368
|
}
|
|
1369
|
+
this.debug("Draw tile imageBitmap/image to temporary canvas");
|
|
1370
|
+
const tmpCanvas = this.createCanvas(tile.width, tile.height, { preferOffscreen: true });
|
|
1371
|
+
const tmpCtx = tmpCanvas.getContext("2d");
|
|
1372
|
+
tmpCtx.globalCompositeOperation = "copy";
|
|
1373
|
+
tmpCtx.drawImage(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height, 0, 0, tile.width, tile.height);
|
|
1374
|
+
this.debug("Get tile pixel data");
|
|
1375
|
+
const src = tmpCtx.getImageData(0, 0, tile.width, tile.height).data;
|
|
1376
|
+
tmpCanvas.width = tmpCanvas.height = 0;
|
|
1377
|
+
return Object.assign({}, extractTo, {
|
|
1378
|
+
kind: "array",
|
|
1379
|
+
src
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1382
|
+
__landTileData(tile, result, stageEnv) {
|
|
1383
|
+
if (result.kind === "bitmap") {
|
|
1384
|
+
stageEnv.toCtx.drawImage(result.data, tile.toX, tile.toY);
|
|
1385
|
+
result.data.close();
|
|
1386
|
+
return null;
|
|
1387
|
+
}
|
|
1388
|
+
this.debug("Draw tile");
|
|
1389
|
+
const toImageData = stageEnv.toCtx.createImageData(tile.toWidth, tile.toHeight);
|
|
1390
|
+
toImageData.data.set(result.data);
|
|
1391
|
+
if (this.capabilities.safari_put_image_data_fix) stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth + 1e-5, tile.toInnerHeight + 1e-5);
|
|
1392
|
+
else stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth, tile.toInnerHeight);
|
|
1393
|
+
return null;
|
|
1394
|
+
}
|
|
1395
|
+
__tileAndResize(from, to, resizeParams, ctx) {
|
|
1396
|
+
var _this3 = this;
|
|
1397
|
+
return _asyncToGenerator(function* () {
|
|
1398
|
+
const stageEnv = {
|
|
1399
|
+
srcCtx: null,
|
|
1400
|
+
srcImageBitmap: null,
|
|
1401
|
+
isImageBitmapReused: false,
|
|
1402
|
+
toCtx: null
|
|
1403
|
+
};
|
|
1404
|
+
const processTile = (tile) => _this3.__limit(_asyncToGenerator(function* () {
|
|
1405
|
+
if (ctx.canceled) return ctx.cancelToken;
|
|
1406
|
+
const tileJob = {
|
|
1407
|
+
width: tile.width,
|
|
1408
|
+
height: tile.height,
|
|
1409
|
+
toWidth: tile.toWidth,
|
|
1410
|
+
toHeight: tile.toHeight,
|
|
1411
|
+
scaleX: tile.scaleX,
|
|
1412
|
+
scaleY: tile.scaleY,
|
|
1413
|
+
offsetX: tile.offsetX,
|
|
1414
|
+
offsetY: tile.offsetY,
|
|
1415
|
+
filter: resizeParams.filter,
|
|
1416
|
+
unsharpAmount: resizeParams.unsharpAmount,
|
|
1417
|
+
unsharpRadius: resizeParams.unsharpRadius,
|
|
1418
|
+
unsharpThreshold: resizeParams.unsharpThreshold
|
|
1419
|
+
};
|
|
1420
|
+
_this3.debug("Invoke resize math");
|
|
1421
|
+
const extractedTileJob = yield _this3.__extractTileData(tile, from, stageEnv, tileJob);
|
|
1422
|
+
_this3.debug("Invoke resize math");
|
|
1423
|
+
const result = yield _this3.__invokeResize(extractedTileJob, ctx);
|
|
1424
|
+
if (ctx.canceled) return ctx.cancelToken;
|
|
1425
|
+
return _this3.__landTileData(tile, result, stageEnv);
|
|
1426
|
+
}));
|
|
1427
|
+
yield Promise.resolve();
|
|
1428
|
+
stageEnv.toCtx = to.getContext("2d");
|
|
1429
|
+
if (isCanvas(from)) {} else if (isImageBitmap(from)) {
|
|
1430
|
+
stageEnv.srcImageBitmap = from;
|
|
1431
|
+
stageEnv.isImageBitmapReused = true;
|
|
1432
|
+
} else if (isImage(from)) {
|
|
1433
|
+
if (_this3.capabilities.create_image_bitmap) {
|
|
1434
|
+
_this3.debug("Decode image via createImageBitmap");
|
|
1435
|
+
try {
|
|
1436
|
+
stageEnv.srcImageBitmap = yield createImageBitmap(from);
|
|
1437
|
+
} catch (__) {}
|
|
1438
|
+
}
|
|
1439
|
+
} else throw new Error("Pica: \".from\" should be Image, Canvas or ImageBitmap");
|
|
1440
|
+
if (ctx.canceled) return ctx.cancelToken;
|
|
1441
|
+
_this3.debug("Calculate tiles");
|
|
1442
|
+
const jobs = createRegions({
|
|
1443
|
+
width: resizeParams.width,
|
|
1444
|
+
height: resizeParams.height,
|
|
1445
|
+
srcTileSize: _this3.options.tile,
|
|
1446
|
+
toWidth: resizeParams.toWidth,
|
|
1447
|
+
toHeight: resizeParams.toHeight,
|
|
1448
|
+
destTileBorder: Math.ceil(Math.max(3, 2.5 * resizeParams.unsharpRadius | 0))
|
|
1449
|
+
}).map((tile) => processTile(tile));
|
|
1450
|
+
function cleanup(stageEnv) {
|
|
1451
|
+
if (stageEnv.srcImageBitmap) {
|
|
1452
|
+
if (!stageEnv.isImageBitmapReused) stageEnv.srcImageBitmap.close();
|
|
1453
|
+
stageEnv.srcImageBitmap = null;
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
_this3.debug("Process tiles");
|
|
1457
|
+
try {
|
|
1458
|
+
yield Promise.all(jobs);
|
|
1459
|
+
_this3.debug("Finished!");
|
|
1460
|
+
cleanup(stageEnv);
|
|
1461
|
+
return to;
|
|
1462
|
+
} catch (err) {
|
|
1463
|
+
cleanup(stageEnv);
|
|
1464
|
+
throw err;
|
|
1465
|
+
}
|
|
1466
|
+
})();
|
|
1467
|
+
}
|
|
1468
|
+
__planStagesAndResize(from, to, resizeParams, ctx) {
|
|
1469
|
+
var _this4 = this;
|
|
1470
|
+
return _asyncToGenerator(function* () {
|
|
1471
|
+
let src = from;
|
|
1472
|
+
let srcWidth = resizeParams.width;
|
|
1473
|
+
let srcHeight = resizeParams.height;
|
|
1474
|
+
const stages = createStages(resizeParams.width, resizeParams.height, resizeParams.toWidth, resizeParams.toHeight, _this4.options.tile);
|
|
1475
|
+
while (stages.length > 0) {
|
|
1476
|
+
if (ctx.canceled) return ctx.cancelToken;
|
|
1477
|
+
const [toWidth, toHeight] = stages.shift();
|
|
1478
|
+
const isLastStage = stages.length === 0;
|
|
1479
|
+
let filter;
|
|
1480
|
+
if (isLastStage || !is_cib_filter(resizeParams.filter)) filter = resizeParams.filter;
|
|
1481
|
+
else if (resizeParams.filter === "box") filter = "box";
|
|
1482
|
+
else filter = "hamming";
|
|
1483
|
+
const stageParams = _objectSpread2(_objectSpread2({}, resizeParams), {}, {
|
|
1484
|
+
filter,
|
|
1485
|
+
width: srcWidth,
|
|
1486
|
+
height: srcHeight,
|
|
1487
|
+
toWidth,
|
|
1488
|
+
toHeight
|
|
1489
|
+
});
|
|
1490
|
+
const dest = isLastStage ? to : _this4.createCanvas(toWidth, toHeight, { preferOffscreen: true });
|
|
1491
|
+
const prevTmp = src !== from ? src : void 0;
|
|
1492
|
+
try {
|
|
1493
|
+
yield _this4.__tileAndResize(src, dest, stageParams, ctx);
|
|
1494
|
+
} finally {
|
|
1495
|
+
if (prevTmp) prevTmp.width = prevTmp.height = 0;
|
|
1496
|
+
}
|
|
1497
|
+
src = dest;
|
|
1498
|
+
srcWidth = toWidth;
|
|
1499
|
+
srcHeight = toHeight;
|
|
1500
|
+
}
|
|
1501
|
+
return to;
|
|
1502
|
+
})();
|
|
1503
|
+
}
|
|
1504
|
+
__resizeViaCreateImageBitmap(from, to, resizeParams, ctx) {
|
|
1505
|
+
var _this5 = this;
|
|
1506
|
+
return _asyncToGenerator(function* () {
|
|
1507
|
+
var _utils$filter_to_cib_;
|
|
1508
|
+
let toCtx = to.getContext("2d");
|
|
1509
|
+
_this5.debug("Resize via createImageBitmap()");
|
|
1510
|
+
const imageBitmap = yield createImageBitmap(from, {
|
|
1511
|
+
resizeWidth: resizeParams.toWidth,
|
|
1512
|
+
resizeHeight: resizeParams.toHeight,
|
|
1513
|
+
resizeQuality: cib_quality_name((_utils$filter_to_cib_ = filter_to_cib_quality(resizeParams.filter)) !== null && _utils$filter_to_cib_ !== void 0 ? _utils$filter_to_cib_ : 3)
|
|
1514
|
+
});
|
|
1515
|
+
if (ctx.canceled) return ctx.cancelToken;
|
|
1516
|
+
if (!resizeParams.unsharpAmount) {
|
|
1517
|
+
toCtx.drawImage(imageBitmap, 0, 0);
|
|
1518
|
+
imageBitmap.close();
|
|
1519
|
+
toCtx = null;
|
|
1520
|
+
_this5.debug("Finished!");
|
|
1521
|
+
return to;
|
|
1522
|
+
}
|
|
1523
|
+
_this5.debug("Unsharp result");
|
|
1524
|
+
let tmpCanvas = _this5.createCanvas(resizeParams.toWidth, resizeParams.toHeight);
|
|
1525
|
+
let tmpCtx = tmpCanvas.getContext("2d");
|
|
1526
|
+
tmpCtx.drawImage(imageBitmap, 0, 0);
|
|
1527
|
+
imageBitmap.close();
|
|
1528
|
+
let iData = tmpCtx.getImageData(0, 0, resizeParams.toWidth, resizeParams.toHeight);
|
|
1529
|
+
_this5.__mathlib.unsharp_mask(iData.data, resizeParams.toWidth, resizeParams.toHeight, resizeParams.unsharpAmount, resizeParams.unsharpRadius, resizeParams.unsharpThreshold);
|
|
1530
|
+
toCtx.putImageData(iData, 0, 0);
|
|
1531
|
+
tmpCanvas.width = tmpCanvas.height = 0;
|
|
1532
|
+
iData = tmpCtx = tmpCanvas = toCtx = null;
|
|
1533
|
+
_this5.debug("Finished!");
|
|
1534
|
+
return to;
|
|
1535
|
+
})();
|
|
1536
|
+
}
|
|
1537
|
+
resize(from, to, options) {
|
|
1538
|
+
var _this6 = this;
|
|
1539
|
+
return _asyncToGenerator(function* () {
|
|
1540
|
+
_this6.debug("Start resize...");
|
|
1541
|
+
const requested = {};
|
|
1542
|
+
if (options) Object.assign(requested, options);
|
|
1543
|
+
let filter = requested.filter || DEFAULT_RESIZE_OPTS.filter;
|
|
1544
|
+
if (Object.prototype.hasOwnProperty.call(requested, "quality")) {
|
|
1545
|
+
const quality = requested.quality;
|
|
1546
|
+
if (typeof quality !== "number" || quality < 0 || quality > 3) throw new Error(`Pica: .quality should be [0..3], got ${quality}`);
|
|
1547
|
+
filter = cib_quality_filter(quality);
|
|
1548
|
+
}
|
|
1549
|
+
const resizeParams = {
|
|
1550
|
+
filter,
|
|
1551
|
+
unsharpAmount: requested.unsharpAmount || DEFAULT_RESIZE_OPTS.unsharpAmount,
|
|
1552
|
+
unsharpRadius: requested.unsharpRadius || DEFAULT_RESIZE_OPTS.unsharpRadius,
|
|
1553
|
+
unsharpThreshold: requested.unsharpThreshold || DEFAULT_RESIZE_OPTS.unsharpThreshold,
|
|
1554
|
+
width: isImage(from) ? from.naturalWidth : from.width,
|
|
1555
|
+
height: isImage(from) ? from.naturalHeight : from.height,
|
|
1556
|
+
toWidth: to.width,
|
|
1557
|
+
toHeight: to.height
|
|
1558
|
+
};
|
|
1559
|
+
if (resizeParams.unsharpRadius > 2) resizeParams.unsharpRadius = 2;
|
|
1560
|
+
if (to.width === 0 || to.height === 0) return Promise.reject(/* @__PURE__ */ new Error(`Invalid output size: ${to.width}x${to.height}`));
|
|
1561
|
+
const ctx = {
|
|
1562
|
+
cancelToken: requested.cancelToken,
|
|
1563
|
+
canceled: false
|
|
1564
|
+
};
|
|
1565
|
+
if (ctx.cancelToken) ctx.cancelToken = ctx.cancelToken.then((data) => {
|
|
1566
|
+
ctx.canceled = true;
|
|
1567
|
+
throw data;
|
|
1568
|
+
}, (err) => {
|
|
1569
|
+
ctx.canceled = true;
|
|
1570
|
+
throw err;
|
|
1571
|
+
});
|
|
1572
|
+
yield _this6.init();
|
|
1573
|
+
if (ctx.canceled) return ctx.cancelToken;
|
|
1574
|
+
if (_this6.capabilities.bug_image_bitmap_orientation_region && (isImage(from) || isImageBitmap(from))) {
|
|
1575
|
+
const tmpCanvas = _this6.createCanvas(resizeParams.width, resizeParams.height);
|
|
1576
|
+
tmpCanvas.getContext("2d").drawImage(from, 0, 0);
|
|
1577
|
+
from = tmpCanvas;
|
|
1578
|
+
}
|
|
1579
|
+
if (_this6.resize_features.cib) {
|
|
1580
|
+
if (is_cib_filter(resizeParams.filter)) return _this6.__resizeViaCreateImageBitmap(from, to, resizeParams, ctx);
|
|
1581
|
+
_this6.debug("cib is enabled, but not supports provided filter, fallback to manual math");
|
|
1582
|
+
}
|
|
1583
|
+
if (!_this6.capabilities.canvas && !_this6.capabilities.offscreen_canvas) {
|
|
1584
|
+
const err = /* @__PURE__ */ new Error("Pica: cannot use getImageData on canvas, make sure fingerprinting protection isn't enabled");
|
|
1585
|
+
err.code = "ERR_GET_IMAGE_DATA";
|
|
1586
|
+
throw err;
|
|
1587
|
+
}
|
|
1588
|
+
return _this6.__planStagesAndResize(from, to, resizeParams, ctx);
|
|
1589
|
+
})();
|
|
1590
|
+
}
|
|
1591
|
+
resizeBuffer(options) {
|
|
1592
|
+
var _this7 = this;
|
|
1593
|
+
return _asyncToGenerator(function* () {
|
|
1594
|
+
const opts = Object.assign({}, DEFAULT_RESIZE_OPTS, options);
|
|
1595
|
+
if (Object.prototype.hasOwnProperty.call(opts, "quality")) {
|
|
1596
|
+
const quality = opts.quality;
|
|
1597
|
+
if (typeof quality !== "number" || quality < 0 || quality > 3) throw new Error(`Pica: .quality should be [0..3], got ${quality}`);
|
|
1598
|
+
opts.filter = cib_quality_filter(quality);
|
|
1599
|
+
}
|
|
1600
|
+
yield _this7.init();
|
|
1601
|
+
if (!_this7.__mathlib) throw new Error("Pica: math library is not initialized");
|
|
1602
|
+
const mathOpts = {
|
|
1603
|
+
src: opts.src,
|
|
1604
|
+
width: opts.width,
|
|
1605
|
+
height: opts.height,
|
|
1606
|
+
toWidth: opts.toWidth,
|
|
1607
|
+
toHeight: opts.toHeight,
|
|
1608
|
+
dest: opts.dest,
|
|
1609
|
+
scaleX: opts.toWidth / opts.width,
|
|
1610
|
+
scaleY: opts.toHeight / opts.height,
|
|
1611
|
+
offsetX: 0,
|
|
1612
|
+
offsetY: 0,
|
|
1613
|
+
filter: opts.filter,
|
|
1614
|
+
unsharpAmount: opts.unsharpAmount,
|
|
1615
|
+
unsharpRadius: opts.unsharpRadius,
|
|
1616
|
+
unsharpThreshold: opts.unsharpThreshold
|
|
1617
|
+
};
|
|
1618
|
+
return _this7.__mathlib.resizeAndUnsharp(mathOpts);
|
|
1619
|
+
})();
|
|
1774
1620
|
}
|
|
1621
|
+
toBlob(canvas, mimeType, quality) {
|
|
1622
|
+
return _asyncToGenerator(function* () {
|
|
1623
|
+
mimeType = mimeType || "image/png";
|
|
1624
|
+
if ("toBlob" in canvas && canvas.toBlob) return new Promise((resolve) => {
|
|
1625
|
+
canvas.toBlob((blob) => resolve(blob), mimeType, quality);
|
|
1626
|
+
});
|
|
1627
|
+
if ("convertToBlob" in canvas && canvas.convertToBlob) return canvas.convertToBlob({
|
|
1628
|
+
type: mimeType,
|
|
1629
|
+
quality
|
|
1630
|
+
});
|
|
1631
|
+
const asString = atob(canvas.toDataURL(mimeType, quality).split(",")[1]);
|
|
1632
|
+
const len = asString.length;
|
|
1633
|
+
const asBuffer = new Uint8Array(len);
|
|
1634
|
+
for (let i = 0; i < len; i++) asBuffer[i] = asString.charCodeAt(i);
|
|
1635
|
+
return new Blob([asBuffer], { type: mimeType });
|
|
1636
|
+
})();
|
|
1637
|
+
}
|
|
1638
|
+
debug(..._args) {}
|
|
1639
|
+
};
|
|
1640
|
+
function pica(options) {
|
|
1641
|
+
return new Pica(options);
|
|
1775
1642
|
}
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
},{}],23:[function(_dereq_,module,exports){
|
|
1781
|
-
var bundleFn = arguments[3];
|
|
1782
|
-
var sources = arguments[4];
|
|
1783
|
-
var cache = arguments[5];
|
|
1784
|
-
|
|
1785
|
-
var stringify = JSON.stringify;
|
|
1786
|
-
|
|
1787
|
-
module.exports = function (fn, options) {
|
|
1788
|
-
var wkey;
|
|
1789
|
-
var cacheKeys = Object.keys(cache);
|
|
1790
|
-
|
|
1791
|
-
for (var i = 0, l = cacheKeys.length; i < l; i++) {
|
|
1792
|
-
var key = cacheKeys[i];
|
|
1793
|
-
var exp = cache[key].exports;
|
|
1794
|
-
// Using babel as a transpiler to use esmodule, the export will always
|
|
1795
|
-
// be an object with the default export as a property of it. To ensure
|
|
1796
|
-
// the existing api and babel esmodule exports are both supported we
|
|
1797
|
-
// check for both
|
|
1798
|
-
if (exp === fn || exp && exp.default === fn) {
|
|
1799
|
-
wkey = key;
|
|
1800
|
-
break;
|
|
1801
|
-
}
|
|
1802
|
-
}
|
|
1803
|
-
|
|
1804
|
-
if (!wkey) {
|
|
1805
|
-
wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);
|
|
1806
|
-
var wcache = {};
|
|
1807
|
-
for (var i = 0, l = cacheKeys.length; i < l; i++) {
|
|
1808
|
-
var key = cacheKeys[i];
|
|
1809
|
-
wcache[key] = key;
|
|
1810
|
-
}
|
|
1811
|
-
sources[wkey] = [
|
|
1812
|
-
'function(require,module,exports){' + fn + '(self); }',
|
|
1813
|
-
wcache
|
|
1814
|
-
];
|
|
1815
|
-
}
|
|
1816
|
-
var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);
|
|
1817
|
-
|
|
1818
|
-
var scache = {}; scache[wkey] = wkey;
|
|
1819
|
-
sources[skey] = [
|
|
1820
|
-
'function(require,module,exports){' +
|
|
1821
|
-
// try to call default if defined to also support babel esmodule exports
|
|
1822
|
-
'var f = require(' + stringify(wkey) + ');' +
|
|
1823
|
-
'(f.default ? f.default : f)(self);' +
|
|
1824
|
-
'}',
|
|
1825
|
-
scache
|
|
1826
|
-
];
|
|
1827
|
-
|
|
1828
|
-
var workerSources = {};
|
|
1829
|
-
resolveSources(skey);
|
|
1830
|
-
|
|
1831
|
-
function resolveSources(key) {
|
|
1832
|
-
workerSources[key] = true;
|
|
1833
|
-
|
|
1834
|
-
for (var depPath in sources[key][1]) {
|
|
1835
|
-
var depKey = sources[key][1][depPath];
|
|
1836
|
-
if (!workerSources[depKey]) {
|
|
1837
|
-
resolveSources(depKey);
|
|
1838
|
-
}
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
|
|
1842
|
-
var src = '(' + bundleFn + ')({'
|
|
1843
|
-
+ Object.keys(workerSources).map(function (key) {
|
|
1844
|
-
return stringify(key) + ':['
|
|
1845
|
-
+ sources[key][0]
|
|
1846
|
-
+ ',' + stringify(sources[key][1]) + ']'
|
|
1847
|
-
;
|
|
1848
|
-
}).join(',')
|
|
1849
|
-
+ '},{},[' + stringify(skey) + '])'
|
|
1850
|
-
;
|
|
1851
|
-
|
|
1852
|
-
var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
|
|
1853
|
-
|
|
1854
|
-
var blob = new Blob([src], { type: 'text/javascript' });
|
|
1855
|
-
if (options && options.bare) { return blob; }
|
|
1856
|
-
var workerUrl = URL.createObjectURL(blob);
|
|
1857
|
-
var worker = new Worker(workerUrl);
|
|
1858
|
-
worker.objectURL = workerUrl;
|
|
1859
|
-
return worker;
|
|
1860
|
-
};
|
|
1861
|
-
|
|
1862
|
-
},{}],"/index.js":[function(_dereq_,module,exports){
|
|
1863
|
-
'use strict';
|
|
1864
|
-
|
|
1865
|
-
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
1866
|
-
|
|
1867
|
-
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
1868
|
-
|
|
1869
|
-
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
1870
|
-
|
|
1871
|
-
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
1872
|
-
|
|
1873
|
-
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
1874
|
-
|
|
1875
|
-
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
1876
|
-
|
|
1877
|
-
var assign = _dereq_('object-assign');
|
|
1878
|
-
|
|
1879
|
-
var webworkify = _dereq_('webworkify');
|
|
1880
|
-
|
|
1881
|
-
var MathLib = _dereq_('./lib/mathlib');
|
|
1882
|
-
|
|
1883
|
-
var Pool = _dereq_('./lib/pool');
|
|
1884
|
-
|
|
1885
|
-
var utils = _dereq_('./lib/utils');
|
|
1886
|
-
|
|
1887
|
-
var worker = _dereq_('./lib/worker');
|
|
1888
|
-
|
|
1889
|
-
var createStages = _dereq_('./lib/stepper');
|
|
1890
|
-
|
|
1891
|
-
var createRegions = _dereq_('./lib/tiler');
|
|
1892
|
-
|
|
1893
|
-
var filter_info = _dereq_('./lib/mm_resize/resize_filter_info'); // Deduplicate pools & limiters with the same configs
|
|
1894
|
-
// when user creates multiple pica instances.
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
var singletones = {};
|
|
1898
|
-
var NEED_SAFARI_FIX = false;
|
|
1899
|
-
|
|
1900
|
-
try {
|
|
1901
|
-
if (typeof navigator !== 'undefined' && navigator.userAgent) {
|
|
1902
|
-
NEED_SAFARI_FIX = navigator.userAgent.indexOf('Safari') >= 0;
|
|
1903
|
-
}
|
|
1904
|
-
} catch (e) {}
|
|
1905
|
-
|
|
1906
|
-
var concurrency = 1;
|
|
1907
|
-
|
|
1908
|
-
if (typeof navigator !== 'undefined') {
|
|
1909
|
-
concurrency = Math.min(navigator.hardwareConcurrency || 1, 4);
|
|
1910
|
-
}
|
|
1911
|
-
|
|
1912
|
-
var DEFAULT_PICA_OPTS = {
|
|
1913
|
-
tile: 1024,
|
|
1914
|
-
concurrency: concurrency,
|
|
1915
|
-
features: ['js', 'wasm', 'ww'],
|
|
1916
|
-
idle: 2000,
|
|
1917
|
-
createCanvas: function createCanvas(width, height) {
|
|
1918
|
-
var tmpCanvas = document.createElement('canvas');
|
|
1919
|
-
tmpCanvas.width = width;
|
|
1920
|
-
tmpCanvas.height = height;
|
|
1921
|
-
return tmpCanvas;
|
|
1922
|
-
}
|
|
1923
|
-
};
|
|
1924
|
-
var DEFAULT_RESIZE_OPTS = {
|
|
1925
|
-
filter: 'mks2013',
|
|
1926
|
-
unsharpAmount: 0,
|
|
1927
|
-
unsharpRadius: 0.0,
|
|
1928
|
-
unsharpThreshold: 0
|
|
1929
|
-
};
|
|
1930
|
-
var CAN_NEW_IMAGE_DATA = false;
|
|
1931
|
-
var CAN_CREATE_IMAGE_BITMAP = false;
|
|
1932
|
-
var CAN_USE_CANVAS_GET_IMAGE_DATA = false;
|
|
1933
|
-
var CAN_USE_OFFSCREEN_CANVAS = false;
|
|
1934
|
-
var CAN_USE_CIB_REGION_FOR_IMAGE = false;
|
|
1935
|
-
|
|
1936
|
-
function workerFabric() {
|
|
1937
|
-
return {
|
|
1938
|
-
value: webworkify(worker),
|
|
1939
|
-
destroy: function destroy() {
|
|
1940
|
-
this.value.terminate();
|
|
1941
|
-
|
|
1942
|
-
if (typeof window !== 'undefined') {
|
|
1943
|
-
var url = window.URL || window.webkitURL || window.mozURL || window.msURL;
|
|
1944
|
-
|
|
1945
|
-
if (url && url.revokeObjectURL && this.value.objectURL) {
|
|
1946
|
-
url.revokeObjectURL(this.value.objectURL);
|
|
1947
|
-
}
|
|
1948
|
-
}
|
|
1949
|
-
}
|
|
1950
|
-
};
|
|
1951
|
-
} ////////////////////////////////////////////////////////////////////////////////
|
|
1952
|
-
// API methods
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
function Pica(options) {
|
|
1956
|
-
if (!(this instanceof Pica)) return new Pica(options);
|
|
1957
|
-
this.options = assign({}, DEFAULT_PICA_OPTS, options || {});
|
|
1958
|
-
var limiter_key = "lk_".concat(this.options.concurrency); // Share limiters to avoid multiple parallel workers when user creates
|
|
1959
|
-
// multiple pica instances.
|
|
1960
|
-
|
|
1961
|
-
this.__limit = singletones[limiter_key] || utils.limiter(this.options.concurrency);
|
|
1962
|
-
if (!singletones[limiter_key]) singletones[limiter_key] = this.__limit; // List of supported features, according to options & browser/node.js
|
|
1963
|
-
|
|
1964
|
-
this.features = {
|
|
1965
|
-
js: false,
|
|
1966
|
-
// pure JS implementation, can be disabled for testing
|
|
1967
|
-
wasm: false,
|
|
1968
|
-
// webassembly implementation for heavy functions
|
|
1969
|
-
cib: false,
|
|
1970
|
-
// resize via createImageBitmap (only FF at this moment)
|
|
1971
|
-
ww: false // webworkers
|
|
1972
|
-
|
|
1973
|
-
};
|
|
1974
|
-
this.__workersPool = null; // Store requested features for webworkers
|
|
1975
|
-
|
|
1976
|
-
this.__requested_features = [];
|
|
1977
|
-
this.__mathlib = null;
|
|
1978
|
-
}
|
|
1979
|
-
|
|
1980
|
-
Pica.prototype.init = function () {
|
|
1981
|
-
var _this = this;
|
|
1982
|
-
|
|
1983
|
-
if (this.__initPromise) return this.__initPromise; // Test if we can create ImageData without canvas and memory copy
|
|
1984
|
-
|
|
1985
|
-
if (typeof ImageData !== 'undefined' && typeof Uint8ClampedArray !== 'undefined') {
|
|
1986
|
-
try {
|
|
1987
|
-
/* eslint-disable no-new */
|
|
1988
|
-
new ImageData(new Uint8ClampedArray(400), 10, 10);
|
|
1989
|
-
CAN_NEW_IMAGE_DATA = true;
|
|
1990
|
-
} catch (__) {}
|
|
1991
|
-
} // ImageBitmap can be effective in 2 places:
|
|
1992
|
-
//
|
|
1993
|
-
// 1. Threaded jpeg unpack (basic)
|
|
1994
|
-
// 2. Built-in resize (blocked due problem in chrome, see issue #89)
|
|
1995
|
-
//
|
|
1996
|
-
// For basic use we also need ImageBitmap wo support .close() method,
|
|
1997
|
-
// see https://developer.mozilla.org/ru/docs/Web/API/ImageBitmap
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
if (typeof ImageBitmap !== 'undefined') {
|
|
2001
|
-
if (ImageBitmap.prototype && ImageBitmap.prototype.close) {
|
|
2002
|
-
CAN_CREATE_IMAGE_BITMAP = true;
|
|
2003
|
-
} else {
|
|
2004
|
-
this.debug('ImageBitmap does not support .close(), disabled');
|
|
2005
|
-
}
|
|
2006
|
-
}
|
|
2007
|
-
|
|
2008
|
-
var features = this.options.features.slice();
|
|
2009
|
-
|
|
2010
|
-
if (features.indexOf('all') >= 0) {
|
|
2011
|
-
features = ['cib', 'wasm', 'js', 'ww'];
|
|
2012
|
-
}
|
|
2013
|
-
|
|
2014
|
-
this.__requested_features = features;
|
|
2015
|
-
this.__mathlib = new MathLib(features); // Check WebWorker support if requested
|
|
2016
|
-
|
|
2017
|
-
if (features.indexOf('ww') >= 0) {
|
|
2018
|
-
if (typeof window !== 'undefined' && 'Worker' in window) {
|
|
2019
|
-
// IE <= 11 don't allow to create webworkers from string. We should check it.
|
|
2020
|
-
// https://connect.microsoft.com/IE/feedback/details/801810/web-workers-from-blob-urls-in-ie-10-and-11
|
|
2021
|
-
try {
|
|
2022
|
-
var wkr = _dereq_('webworkify')(function () {});
|
|
2023
|
-
|
|
2024
|
-
wkr.terminate();
|
|
2025
|
-
this.features.ww = true; // pool uniqueness depends on pool config + webworker config
|
|
2026
|
-
|
|
2027
|
-
var wpool_key = "wp_".concat(JSON.stringify(this.options));
|
|
2028
|
-
|
|
2029
|
-
if (singletones[wpool_key]) {
|
|
2030
|
-
this.__workersPool = singletones[wpool_key];
|
|
2031
|
-
} else {
|
|
2032
|
-
this.__workersPool = new Pool(workerFabric, this.options.idle);
|
|
2033
|
-
singletones[wpool_key] = this.__workersPool;
|
|
2034
|
-
}
|
|
2035
|
-
} catch (__) {}
|
|
2036
|
-
}
|
|
2037
|
-
}
|
|
2038
|
-
|
|
2039
|
-
var initMath = this.__mathlib.init().then(function (mathlib) {
|
|
2040
|
-
// Copy detected features
|
|
2041
|
-
assign(_this.features, mathlib.features);
|
|
2042
|
-
});
|
|
2043
|
-
|
|
2044
|
-
var checkCibResize;
|
|
2045
|
-
|
|
2046
|
-
if (!CAN_CREATE_IMAGE_BITMAP) {
|
|
2047
|
-
checkCibResize = Promise.resolve(false);
|
|
2048
|
-
} else {
|
|
2049
|
-
checkCibResize = utils.cib_support(this.options.createCanvas).then(function (status) {
|
|
2050
|
-
if (_this.features.cib && features.indexOf('cib') < 0) {
|
|
2051
|
-
_this.debug('createImageBitmap() resize supported, but disabled by config');
|
|
2052
|
-
|
|
2053
|
-
return;
|
|
2054
|
-
}
|
|
2055
|
-
|
|
2056
|
-
if (features.indexOf('cib') >= 0) _this.features.cib = status;
|
|
2057
|
-
});
|
|
2058
|
-
}
|
|
2059
|
-
|
|
2060
|
-
CAN_USE_CANVAS_GET_IMAGE_DATA = utils.can_use_canvas(this.options.createCanvas);
|
|
2061
|
-
var checkOffscreenCanvas;
|
|
2062
|
-
|
|
2063
|
-
if (CAN_CREATE_IMAGE_BITMAP && CAN_NEW_IMAGE_DATA && features.indexOf('ww') !== -1) {
|
|
2064
|
-
checkOffscreenCanvas = utils.worker_offscreen_canvas_support();
|
|
2065
|
-
} else {
|
|
2066
|
-
checkOffscreenCanvas = Promise.resolve(false);
|
|
2067
|
-
}
|
|
2068
|
-
|
|
2069
|
-
checkOffscreenCanvas = checkOffscreenCanvas.then(function (result) {
|
|
2070
|
-
CAN_USE_OFFSCREEN_CANVAS = result;
|
|
2071
|
-
}); // we use createImageBitmap to crop image data and pass it to workers,
|
|
2072
|
-
// so need to check whether function works correctly;
|
|
2073
|
-
// https://bugs.chromium.org/p/chromium/issues/detail?id=1220671
|
|
2074
|
-
|
|
2075
|
-
var checkCibRegion = utils.cib_can_use_region().then(function (result) {
|
|
2076
|
-
CAN_USE_CIB_REGION_FOR_IMAGE = result;
|
|
2077
|
-
}); // Init math lib. That's async because can load some
|
|
2078
|
-
|
|
2079
|
-
this.__initPromise = Promise.all([initMath, checkCibResize, checkOffscreenCanvas, checkCibRegion]).then(function () {
|
|
2080
|
-
return _this;
|
|
2081
|
-
});
|
|
2082
|
-
return this.__initPromise;
|
|
2083
|
-
}; // Call resizer in webworker or locally, depending on config
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
Pica.prototype.__invokeResize = function (tileOpts, opts) {
|
|
2087
|
-
var _this2 = this;
|
|
2088
|
-
|
|
2089
|
-
// Share cache between calls:
|
|
2090
|
-
//
|
|
2091
|
-
// - wasm instance
|
|
2092
|
-
// - wasm memory object
|
|
2093
|
-
//
|
|
2094
|
-
opts.__mathCache = opts.__mathCache || {};
|
|
2095
|
-
return Promise.resolve().then(function () {
|
|
2096
|
-
if (!_this2.features.ww) {
|
|
2097
|
-
// not possible to have ImageBitmap here if user disabled WW
|
|
2098
|
-
return {
|
|
2099
|
-
data: _this2.__mathlib.resizeAndUnsharp(tileOpts, opts.__mathCache)
|
|
2100
|
-
};
|
|
2101
|
-
}
|
|
2102
|
-
|
|
2103
|
-
return new Promise(function (resolve, reject) {
|
|
2104
|
-
var w = _this2.__workersPool.acquire();
|
|
2105
|
-
|
|
2106
|
-
if (opts.cancelToken) opts.cancelToken["catch"](function (err) {
|
|
2107
|
-
return reject(err);
|
|
2108
|
-
});
|
|
2109
|
-
|
|
2110
|
-
w.value.onmessage = function (ev) {
|
|
2111
|
-
w.release();
|
|
2112
|
-
if (ev.data.err) reject(ev.data.err);else resolve(ev.data);
|
|
2113
|
-
};
|
|
2114
|
-
|
|
2115
|
-
var transfer = [];
|
|
2116
|
-
if (tileOpts.src) transfer.push(tileOpts.src.buffer);
|
|
2117
|
-
if (tileOpts.srcBitmap) transfer.push(tileOpts.srcBitmap);
|
|
2118
|
-
w.value.postMessage({
|
|
2119
|
-
opts: tileOpts,
|
|
2120
|
-
features: _this2.__requested_features,
|
|
2121
|
-
preload: {
|
|
2122
|
-
wasm_nodule: _this2.__mathlib.__
|
|
2123
|
-
}
|
|
2124
|
-
}, transfer);
|
|
2125
|
-
});
|
|
2126
|
-
});
|
|
2127
|
-
}; // this function can return promise if createImageBitmap is used
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
Pica.prototype.__extractTileData = function (tile, from, opts, stageEnv, extractTo) {
|
|
2131
|
-
if (this.features.ww && CAN_USE_OFFSCREEN_CANVAS && ( // createImageBitmap doesn't work for images (Image, ImageBitmap) with Exif orientation in Chrome,
|
|
2132
|
-
// can use canvas because canvas doesn't have orientation;
|
|
2133
|
-
// see https://bugs.chromium.org/p/chromium/issues/detail?id=1220671
|
|
2134
|
-
utils.isCanvas(from) || CAN_USE_CIB_REGION_FOR_IMAGE)) {
|
|
2135
|
-
this.debug('Create tile for OffscreenCanvas');
|
|
2136
|
-
return createImageBitmap(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height).then(function (bitmap) {
|
|
2137
|
-
extractTo.srcBitmap = bitmap;
|
|
2138
|
-
return extractTo;
|
|
2139
|
-
});
|
|
2140
|
-
} // Extract tile RGBA buffer, depending on input type
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
if (utils.isCanvas(from)) {
|
|
2144
|
-
if (!stageEnv.srcCtx) stageEnv.srcCtx = from.getContext('2d'); // If input is Canvas - extract region data directly
|
|
2145
|
-
|
|
2146
|
-
this.debug('Get tile pixel data');
|
|
2147
|
-
extractTo.src = stageEnv.srcCtx.getImageData(tile.x, tile.y, tile.width, tile.height).data;
|
|
2148
|
-
return extractTo;
|
|
2149
|
-
} // If input is Image or decoded to ImageBitmap,
|
|
2150
|
-
// draw region to temporary canvas and extract data from it
|
|
2151
|
-
//
|
|
2152
|
-
// Note! Attempt to reuse this canvas causes significant slowdown in chrome
|
|
2153
|
-
//
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
this.debug('Draw tile imageBitmap/image to temporary canvas');
|
|
2157
|
-
var tmpCanvas = this.options.createCanvas(tile.width, tile.height);
|
|
2158
|
-
var tmpCtx = tmpCanvas.getContext('2d');
|
|
2159
|
-
tmpCtx.globalCompositeOperation = 'copy';
|
|
2160
|
-
tmpCtx.drawImage(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height, 0, 0, tile.width, tile.height);
|
|
2161
|
-
this.debug('Get tile pixel data');
|
|
2162
|
-
extractTo.src = tmpCtx.getImageData(0, 0, tile.width, tile.height).data; // Safari 12 workaround
|
|
2163
|
-
// https://github.com/nodeca/pica/issues/199
|
|
2164
|
-
|
|
2165
|
-
tmpCanvas.width = tmpCanvas.height = 0;
|
|
2166
|
-
return extractTo;
|
|
2167
|
-
};
|
|
2168
|
-
|
|
2169
|
-
Pica.prototype.__landTileData = function (tile, result, stageEnv) {
|
|
2170
|
-
var toImageData;
|
|
2171
|
-
this.debug('Convert raw rgba tile result to ImageData');
|
|
2172
|
-
|
|
2173
|
-
if (result.bitmap) {
|
|
2174
|
-
stageEnv.toCtx.drawImage(result.bitmap, tile.toX, tile.toY);
|
|
2175
|
-
return null;
|
|
2176
|
-
}
|
|
2177
|
-
|
|
2178
|
-
if (CAN_NEW_IMAGE_DATA) {
|
|
2179
|
-
// this branch is for modern browsers
|
|
2180
|
-
// If `new ImageData()` & Uint8ClampedArray suported
|
|
2181
|
-
toImageData = new ImageData(new Uint8ClampedArray(result.data), tile.toWidth, tile.toHeight);
|
|
2182
|
-
} else {
|
|
2183
|
-
// fallback for `node-canvas` and old browsers
|
|
2184
|
-
// (IE11 has ImageData but does not support `new ImageData()`)
|
|
2185
|
-
toImageData = stageEnv.toCtx.createImageData(tile.toWidth, tile.toHeight);
|
|
2186
|
-
|
|
2187
|
-
if (toImageData.data.set) {
|
|
2188
|
-
toImageData.data.set(result.data);
|
|
2189
|
-
} else {
|
|
2190
|
-
// IE9 don't have `.set()`
|
|
2191
|
-
for (var i = toImageData.data.length - 1; i >= 0; i--) {
|
|
2192
|
-
toImageData.data[i] = result.data[i];
|
|
2193
|
-
}
|
|
2194
|
-
}
|
|
2195
|
-
}
|
|
2196
|
-
|
|
2197
|
-
this.debug('Draw tile');
|
|
2198
|
-
|
|
2199
|
-
if (NEED_SAFARI_FIX) {
|
|
2200
|
-
// Safari draws thin white stripes between tiles without this fix
|
|
2201
|
-
stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth + 1e-5, tile.toInnerHeight + 1e-5);
|
|
2202
|
-
} else {
|
|
2203
|
-
stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth, tile.toInnerHeight);
|
|
2204
|
-
}
|
|
2205
|
-
|
|
2206
|
-
return null;
|
|
2207
|
-
};
|
|
2208
|
-
|
|
2209
|
-
Pica.prototype.__tileAndResize = function (from, to, opts) {
|
|
2210
|
-
var _this3 = this;
|
|
2211
|
-
|
|
2212
|
-
var stageEnv = {
|
|
2213
|
-
srcCtx: null,
|
|
2214
|
-
srcImageBitmap: null,
|
|
2215
|
-
isImageBitmapReused: false,
|
|
2216
|
-
toCtx: null
|
|
2217
|
-
};
|
|
2218
|
-
|
|
2219
|
-
var processTile = function processTile(tile) {
|
|
2220
|
-
return _this3.__limit(function () {
|
|
2221
|
-
if (opts.canceled) return opts.cancelToken;
|
|
2222
|
-
var tileOpts = {
|
|
2223
|
-
width: tile.width,
|
|
2224
|
-
height: tile.height,
|
|
2225
|
-
toWidth: tile.toWidth,
|
|
2226
|
-
toHeight: tile.toHeight,
|
|
2227
|
-
scaleX: tile.scaleX,
|
|
2228
|
-
scaleY: tile.scaleY,
|
|
2229
|
-
offsetX: tile.offsetX,
|
|
2230
|
-
offsetY: tile.offsetY,
|
|
2231
|
-
filter: opts.filter,
|
|
2232
|
-
unsharpAmount: opts.unsharpAmount,
|
|
2233
|
-
unsharpRadius: opts.unsharpRadius,
|
|
2234
|
-
unsharpThreshold: opts.unsharpThreshold
|
|
2235
|
-
};
|
|
2236
|
-
|
|
2237
|
-
_this3.debug('Invoke resize math');
|
|
2238
|
-
|
|
2239
|
-
return Promise.resolve(tileOpts).then(function (tileOpts) {
|
|
2240
|
-
return _this3.__extractTileData(tile, from, opts, stageEnv, tileOpts);
|
|
2241
|
-
}).then(function (tileOpts) {
|
|
2242
|
-
_this3.debug('Invoke resize math');
|
|
2243
|
-
|
|
2244
|
-
return _this3.__invokeResize(tileOpts, opts);
|
|
2245
|
-
}).then(function (result) {
|
|
2246
|
-
if (opts.canceled) return opts.cancelToken;
|
|
2247
|
-
stageEnv.srcImageData = null;
|
|
2248
|
-
return _this3.__landTileData(tile, result, stageEnv);
|
|
2249
|
-
});
|
|
2250
|
-
});
|
|
2251
|
-
}; // Need to normalize data source first. It can be canvas or image.
|
|
2252
|
-
// If image - try to decode in background if possible
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
return Promise.resolve().then(function () {
|
|
2256
|
-
stageEnv.toCtx = to.getContext('2d');
|
|
2257
|
-
if (utils.isCanvas(from)) return null;
|
|
2258
|
-
|
|
2259
|
-
if (utils.isImageBitmap(from)) {
|
|
2260
|
-
stageEnv.srcImageBitmap = from;
|
|
2261
|
-
stageEnv.isImageBitmapReused = true;
|
|
2262
|
-
return null;
|
|
2263
|
-
}
|
|
2264
|
-
|
|
2265
|
-
if (utils.isImage(from)) {
|
|
2266
|
-
// try do decode image in background for faster next operations;
|
|
2267
|
-
// if we're using offscreen canvas, cib is called per tile, so not needed here
|
|
2268
|
-
if (!CAN_CREATE_IMAGE_BITMAP) return null;
|
|
2269
|
-
|
|
2270
|
-
_this3.debug('Decode image via createImageBitmap');
|
|
2271
|
-
|
|
2272
|
-
return createImageBitmap(from).then(function (imageBitmap) {
|
|
2273
|
-
stageEnv.srcImageBitmap = imageBitmap;
|
|
2274
|
-
}) // Suppress error to use fallback, if method fails
|
|
2275
|
-
// https://github.com/nodeca/pica/issues/190
|
|
2276
|
-
|
|
2277
|
-
/* eslint-disable no-unused-vars */
|
|
2278
|
-
["catch"](function (e) {
|
|
2279
|
-
return null;
|
|
2280
|
-
});
|
|
2281
|
-
}
|
|
2282
|
-
|
|
2283
|
-
throw new Error('Pica: ".from" should be Image, Canvas or ImageBitmap');
|
|
2284
|
-
}).then(function () {
|
|
2285
|
-
if (opts.canceled) return opts.cancelToken;
|
|
2286
|
-
|
|
2287
|
-
_this3.debug('Calculate tiles'); //
|
|
2288
|
-
// Here we are with "normalized" source,
|
|
2289
|
-
// follow to tiling
|
|
2290
|
-
//
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
var regions = createRegions({
|
|
2294
|
-
width: opts.width,
|
|
2295
|
-
height: opts.height,
|
|
2296
|
-
srcTileSize: _this3.options.tile,
|
|
2297
|
-
toWidth: opts.toWidth,
|
|
2298
|
-
toHeight: opts.toHeight,
|
|
2299
|
-
destTileBorder: opts.__destTileBorder
|
|
2300
|
-
});
|
|
2301
|
-
var jobs = regions.map(function (tile) {
|
|
2302
|
-
return processTile(tile);
|
|
2303
|
-
});
|
|
2304
|
-
|
|
2305
|
-
function cleanup(stageEnv) {
|
|
2306
|
-
if (stageEnv.srcImageBitmap) {
|
|
2307
|
-
if (!stageEnv.isImageBitmapReused) stageEnv.srcImageBitmap.close();
|
|
2308
|
-
stageEnv.srcImageBitmap = null;
|
|
2309
|
-
}
|
|
2310
|
-
}
|
|
2311
|
-
|
|
2312
|
-
_this3.debug('Process tiles');
|
|
2313
|
-
|
|
2314
|
-
return Promise.all(jobs).then(function () {
|
|
2315
|
-
_this3.debug('Finished!');
|
|
2316
|
-
|
|
2317
|
-
cleanup(stageEnv);
|
|
2318
|
-
return to;
|
|
2319
|
-
}, function (err) {
|
|
2320
|
-
cleanup(stageEnv);
|
|
2321
|
-
throw err;
|
|
2322
|
-
});
|
|
2323
|
-
});
|
|
2324
|
-
};
|
|
2325
|
-
|
|
2326
|
-
Pica.prototype.__processStages = function (stages, from, to, opts) {
|
|
2327
|
-
var _this4 = this;
|
|
2328
|
-
|
|
2329
|
-
if (opts.canceled) return opts.cancelToken;
|
|
2330
|
-
|
|
2331
|
-
var _stages$shift = stages.shift(),
|
|
2332
|
-
_stages$shift2 = _slicedToArray(_stages$shift, 2),
|
|
2333
|
-
toWidth = _stages$shift2[0],
|
|
2334
|
-
toHeight = _stages$shift2[1];
|
|
2335
|
-
|
|
2336
|
-
var isLastStage = stages.length === 0; // Optimization for legacy filters -
|
|
2337
|
-
// only use user-defined quality for the last stage,
|
|
2338
|
-
// use simpler (Hamming) filter for the first stages where
|
|
2339
|
-
// scale factor is large enough (more than 2-3)
|
|
2340
|
-
//
|
|
2341
|
-
// For advanced filters (mks2013 and custom) - skip optimization,
|
|
2342
|
-
// because need to apply sharpening every time
|
|
2343
|
-
|
|
2344
|
-
var filter;
|
|
2345
|
-
if (isLastStage || filter_info.q2f.indexOf(opts.filter) < 0) filter = opts.filter;else if (opts.filter === 'box') filter = 'box';else filter = 'hamming';
|
|
2346
|
-
opts = assign({}, opts, {
|
|
2347
|
-
toWidth: toWidth,
|
|
2348
|
-
toHeight: toHeight,
|
|
2349
|
-
filter: filter
|
|
2350
|
-
});
|
|
2351
|
-
var tmpCanvas;
|
|
2352
|
-
|
|
2353
|
-
if (!isLastStage) {
|
|
2354
|
-
// create temporary canvas
|
|
2355
|
-
tmpCanvas = this.options.createCanvas(toWidth, toHeight);
|
|
2356
|
-
}
|
|
2357
|
-
|
|
2358
|
-
return this.__tileAndResize(from, isLastStage ? to : tmpCanvas, opts).then(function () {
|
|
2359
|
-
if (isLastStage) return to;
|
|
2360
|
-
opts.width = toWidth;
|
|
2361
|
-
opts.height = toHeight;
|
|
2362
|
-
return _this4.__processStages(stages, tmpCanvas, to, opts);
|
|
2363
|
-
}).then(function (res) {
|
|
2364
|
-
if (tmpCanvas) {
|
|
2365
|
-
// Safari 12 workaround
|
|
2366
|
-
// https://github.com/nodeca/pica/issues/199
|
|
2367
|
-
tmpCanvas.width = tmpCanvas.height = 0;
|
|
2368
|
-
}
|
|
2369
|
-
|
|
2370
|
-
return res;
|
|
2371
|
-
});
|
|
2372
|
-
};
|
|
2373
|
-
|
|
2374
|
-
Pica.prototype.__resizeViaCreateImageBitmap = function (from, to, opts) {
|
|
2375
|
-
var _this5 = this;
|
|
2376
|
-
|
|
2377
|
-
var toCtx = to.getContext('2d');
|
|
2378
|
-
this.debug('Resize via createImageBitmap()');
|
|
2379
|
-
return createImageBitmap(from, {
|
|
2380
|
-
resizeWidth: opts.toWidth,
|
|
2381
|
-
resizeHeight: opts.toHeight,
|
|
2382
|
-
resizeQuality: utils.cib_quality_name(filter_info.f2q[opts.filter])
|
|
2383
|
-
}).then(function (imageBitmap) {
|
|
2384
|
-
if (opts.canceled) return opts.cancelToken; // if no unsharp - draw directly to output canvas
|
|
2385
|
-
|
|
2386
|
-
if (!opts.unsharpAmount) {
|
|
2387
|
-
toCtx.drawImage(imageBitmap, 0, 0);
|
|
2388
|
-
imageBitmap.close();
|
|
2389
|
-
toCtx = null;
|
|
2390
|
-
|
|
2391
|
-
_this5.debug('Finished!');
|
|
2392
|
-
|
|
2393
|
-
return to;
|
|
2394
|
-
}
|
|
2395
|
-
|
|
2396
|
-
_this5.debug('Unsharp result');
|
|
2397
|
-
|
|
2398
|
-
var tmpCanvas = _this5.options.createCanvas(opts.toWidth, opts.toHeight);
|
|
2399
|
-
|
|
2400
|
-
var tmpCtx = tmpCanvas.getContext('2d');
|
|
2401
|
-
tmpCtx.drawImage(imageBitmap, 0, 0);
|
|
2402
|
-
imageBitmap.close();
|
|
2403
|
-
var iData = tmpCtx.getImageData(0, 0, opts.toWidth, opts.toHeight);
|
|
2404
|
-
|
|
2405
|
-
_this5.__mathlib.unsharp_mask(iData.data, opts.toWidth, opts.toHeight, opts.unsharpAmount, opts.unsharpRadius, opts.unsharpThreshold);
|
|
2406
|
-
|
|
2407
|
-
toCtx.putImageData(iData, 0, 0); // Safari 12 workaround
|
|
2408
|
-
// https://github.com/nodeca/pica/issues/199
|
|
2409
|
-
|
|
2410
|
-
tmpCanvas.width = tmpCanvas.height = 0;
|
|
2411
|
-
iData = tmpCtx = tmpCanvas = toCtx = null;
|
|
2412
|
-
|
|
2413
|
-
_this5.debug('Finished!');
|
|
2414
|
-
|
|
2415
|
-
return to;
|
|
2416
|
-
});
|
|
2417
|
-
};
|
|
2418
|
-
|
|
2419
|
-
Pica.prototype.resize = function (from, to, options) {
|
|
2420
|
-
var _this6 = this;
|
|
2421
|
-
|
|
2422
|
-
this.debug('Start resize...');
|
|
2423
|
-
var opts = assign({}, DEFAULT_RESIZE_OPTS);
|
|
2424
|
-
|
|
2425
|
-
if (!isNaN(options)) {
|
|
2426
|
-
opts = assign(opts, {
|
|
2427
|
-
quality: options
|
|
2428
|
-
});
|
|
2429
|
-
} else if (options) {
|
|
2430
|
-
opts = assign(opts, options);
|
|
2431
|
-
}
|
|
2432
|
-
|
|
2433
|
-
opts.toWidth = to.width;
|
|
2434
|
-
opts.toHeight = to.height;
|
|
2435
|
-
opts.width = from.naturalWidth || from.width;
|
|
2436
|
-
opts.height = from.naturalHeight || from.height; // Legacy `.quality` option
|
|
2437
|
-
|
|
2438
|
-
if (Object.prototype.hasOwnProperty.call(opts, 'quality')) {
|
|
2439
|
-
if (opts.quality < 0 || opts.quality > 3) {
|
|
2440
|
-
throw new Error("Pica: .quality should be [0..3], got ".concat(opts.quality));
|
|
2441
|
-
}
|
|
2442
|
-
|
|
2443
|
-
opts.filter = filter_info.q2f[opts.quality];
|
|
2444
|
-
} // Prevent stepper from infinite loop
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
if (to.width === 0 || to.height === 0) {
|
|
2448
|
-
return Promise.reject(new Error("Invalid output size: ".concat(to.width, "x").concat(to.height)));
|
|
2449
|
-
}
|
|
2450
|
-
|
|
2451
|
-
if (opts.unsharpRadius > 2) opts.unsharpRadius = 2;
|
|
2452
|
-
opts.canceled = false;
|
|
2453
|
-
|
|
2454
|
-
if (opts.cancelToken) {
|
|
2455
|
-
// Wrap cancelToken to avoid successive resolve & set flag
|
|
2456
|
-
opts.cancelToken = opts.cancelToken.then(function (data) {
|
|
2457
|
-
opts.canceled = true;
|
|
2458
|
-
throw data;
|
|
2459
|
-
}, function (err) {
|
|
2460
|
-
opts.canceled = true;
|
|
2461
|
-
throw err;
|
|
2462
|
-
});
|
|
2463
|
-
}
|
|
2464
|
-
|
|
2465
|
-
var DEST_TILE_BORDER = 3; // Max possible filter window size
|
|
2466
|
-
|
|
2467
|
-
opts.__destTileBorder = Math.ceil(Math.max(DEST_TILE_BORDER, 2.5 * opts.unsharpRadius | 0));
|
|
2468
|
-
return this.init().then(function () {
|
|
2469
|
-
if (opts.canceled) return opts.cancelToken; // if createImageBitmap supports resize, just do it and return
|
|
2470
|
-
|
|
2471
|
-
if (_this6.features.cib) {
|
|
2472
|
-
if (filter_info.q2f.indexOf(opts.filter) >= 0) {
|
|
2473
|
-
return _this6.__resizeViaCreateImageBitmap(from, to, opts);
|
|
2474
|
-
}
|
|
2475
|
-
|
|
2476
|
-
_this6.debug('cib is enabled, but not supports provided filter, fallback to manual math');
|
|
2477
|
-
}
|
|
2478
|
-
|
|
2479
|
-
if (!CAN_USE_CANVAS_GET_IMAGE_DATA) {
|
|
2480
|
-
var err = new Error('Pica: cannot use getImageData on canvas, ' + "make sure fingerprinting protection isn't enabled");
|
|
2481
|
-
err.code = 'ERR_GET_IMAGE_DATA';
|
|
2482
|
-
throw err;
|
|
2483
|
-
} //
|
|
2484
|
-
// No easy way, let's resize manually via arrays
|
|
2485
|
-
//
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
var stages = createStages(opts.width, opts.height, opts.toWidth, opts.toHeight, _this6.options.tile, opts.__destTileBorder);
|
|
2489
|
-
return _this6.__processStages(stages, from, to, opts);
|
|
2490
|
-
});
|
|
2491
|
-
}; // RGBA buffer resize
|
|
2492
|
-
//
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
Pica.prototype.resizeBuffer = function (options) {
|
|
2496
|
-
var _this7 = this;
|
|
2497
|
-
|
|
2498
|
-
var opts = assign({}, DEFAULT_RESIZE_OPTS, options); // Legacy `.quality` option
|
|
2499
|
-
|
|
2500
|
-
if (Object.prototype.hasOwnProperty.call(opts, 'quality')) {
|
|
2501
|
-
if (opts.quality < 0 || opts.quality > 3) {
|
|
2502
|
-
throw new Error("Pica: .quality should be [0..3], got ".concat(opts.quality));
|
|
2503
|
-
}
|
|
2504
|
-
|
|
2505
|
-
opts.filter = filter_info.q2f[opts.quality];
|
|
2506
|
-
}
|
|
2507
|
-
|
|
2508
|
-
return this.init().then(function () {
|
|
2509
|
-
return _this7.__mathlib.resizeAndUnsharp(opts);
|
|
2510
|
-
});
|
|
2511
|
-
};
|
|
2512
|
-
|
|
2513
|
-
Pica.prototype.toBlob = function (canvas, mimeType, quality) {
|
|
2514
|
-
mimeType = mimeType || 'image/png';
|
|
2515
|
-
return new Promise(function (resolve) {
|
|
2516
|
-
if (canvas.toBlob) {
|
|
2517
|
-
canvas.toBlob(function (blob) {
|
|
2518
|
-
return resolve(blob);
|
|
2519
|
-
}, mimeType, quality);
|
|
2520
|
-
return;
|
|
2521
|
-
}
|
|
2522
|
-
|
|
2523
|
-
if (canvas.convertToBlob) {
|
|
2524
|
-
resolve(canvas.convertToBlob({
|
|
2525
|
-
type: mimeType,
|
|
2526
|
-
quality: quality
|
|
2527
|
-
}));
|
|
2528
|
-
return;
|
|
2529
|
-
} // Fallback for old browsers
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
var asString = atob(canvas.toDataURL(mimeType, quality).split(',')[1]);
|
|
2533
|
-
var len = asString.length;
|
|
2534
|
-
var asBuffer = new Uint8Array(len);
|
|
2535
|
-
|
|
2536
|
-
for (var i = 0; i < len; i++) {
|
|
2537
|
-
asBuffer[i] = asString.charCodeAt(i);
|
|
2538
|
-
}
|
|
2539
|
-
|
|
2540
|
-
resolve(new Blob([asBuffer], {
|
|
2541
|
-
type: mimeType
|
|
2542
|
-
}));
|
|
2543
|
-
});
|
|
2544
|
-
};
|
|
2545
|
-
|
|
2546
|
-
Pica.prototype.debug = function () {};
|
|
2547
|
-
|
|
2548
|
-
module.exports = Pica;
|
|
2549
|
-
|
|
2550
|
-
},{"./lib/mathlib":1,"./lib/mm_resize/resize_filter_info":7,"./lib/pool":13,"./lib/stepper":14,"./lib/tiler":15,"./lib/utils":16,"./lib/worker":17,"object-assign":22,"webworkify":23}]},{},[])("/index.js")
|
|
1643
|
+
var picaWithClass = pica;
|
|
1644
|
+
picaWithClass.Pica = Pica;
|
|
1645
|
+
return picaWithClass;
|
|
2551
1646
|
});
|
|
1647
|
+
|
|
1648
|
+
//# sourceMappingURL=pica.js.map
|