pica 8.0.0 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -2
- package/dist/pica.js +218 -133
- package/dist/pica.min.js +2 -2
- package/index.js +5 -7
- package/lib/mathlib.js +2 -2
- package/lib/mm_resize/convolve.c +193 -17
- package/lib/mm_resize/convolve.js +160 -33
- package/lib/mm_resize/convolve.wasm +0 -0
- package/lib/mm_resize/convolve_wasm_base64.js +1 -1
- package/lib/mm_resize/resize.js +21 -17
- package/lib/mm_resize/resize_wasm.js +21 -11
- package/lib/worker.js +2 -2
- package/package.json +3 -4
package/README.md
CHANGED
|
@@ -130,7 +130,6 @@ taken from source and destination objects.
|
|
|
130
130
|
- __options__ - quality (number) or object:
|
|
131
131
|
- __quality__ (deprecated, use `.filter` instead) - 0..3.
|
|
132
132
|
- __filter__ - filter name (Default - `mks2013`). See [resize_filter_info.js](https://github.com/nodeca/pica/blob/master/lib/mm_resize/resize_filter_info.js) for details. `mks2013` does both resize and sharpening, it's optimal and not recommended to change.
|
|
133
|
-
- __alpha__ - use alpha channel. Default = `false`.
|
|
134
133
|
- __unsharpAmount__ - >=0. Default = `0` (off). Usually
|
|
135
134
|
value between 100 to 200 is good. Note, `mks2013` filter already does
|
|
136
135
|
optimal sharpening.
|
|
@@ -171,7 +170,6 @@ binary data (for example, if you decode jpeg files "manually").
|
|
|
171
170
|
- __toHeight__ - output height, >=0, in pixels.
|
|
172
171
|
- __quality__ (deprecated, use `.filter` instead) - 0..3.
|
|
173
172
|
- __filter__ - filter name (Default - `mks2013`). See [resize_filter_info.js](https://github.com/nodeca/pica/blob/master/lib/mm_resize/resize_filter_info.js) for details. `mks2013` does both resize and sharpening, it's optimal and not recommended to change.
|
|
174
|
-
- __alpha__ - use alpha channel. Default = `false`.
|
|
175
173
|
- __unsharpAmount__ - >=0. Default = `0` (off). Usually
|
|
176
174
|
value between 100 to 200 is good. Note, `mks2013` filter already does
|
|
177
175
|
optimal sharpening.
|
package/dist/pica.js
CHANGED
|
@@ -13,8 +13,6 @@ https://github.com/nodeca/pica
|
|
|
13
13
|
//
|
|
14
14
|
'use strict';
|
|
15
15
|
|
|
16
|
-
var inherits = _dereq_('inherits');
|
|
17
|
-
|
|
18
16
|
var Multimath = _dereq_('multimath');
|
|
19
17
|
|
|
20
18
|
var mm_unsharp_mask = _dereq_('./mm_unsharp_mask');
|
|
@@ -37,7 +35,8 @@ function MathLib(requested_features) {
|
|
|
37
35
|
this.use(mm_resize);
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
|
|
38
|
+
MathLib.prototype = Object.create(Multimath.prototype);
|
|
39
|
+
MathLib.prototype.constructor = MathLib;
|
|
41
40
|
|
|
42
41
|
MathLib.prototype.resizeAndUnsharp = function resizeAndUnsharp(options, cache) {
|
|
43
42
|
var result = this.resize(options, cache);
|
|
@@ -51,7 +50,7 @@ MathLib.prototype.resizeAndUnsharp = function resizeAndUnsharp(options, cache) {
|
|
|
51
50
|
|
|
52
51
|
module.exports = MathLib;
|
|
53
52
|
|
|
54
|
-
},{"./mm_resize":4,"./mm_unsharp_mask":9,"
|
|
53
|
+
},{"./mm_resize":4,"./mm_unsharp_mask":9,"multimath":19}],2:[function(_dereq_,module,exports){
|
|
55
54
|
// Resize convolvers, pure JS implementation
|
|
56
55
|
//
|
|
57
56
|
'use strict'; // Precision of fixed FP values
|
|
@@ -59,18 +58,23 @@ module.exports = MathLib;
|
|
|
59
58
|
|
|
60
59
|
function clampTo8(i) {
|
|
61
60
|
return i < 0 ? 0 : i > 255 ? 255 : i;
|
|
62
|
-
}
|
|
63
|
-
|
|
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)
|
|
64
69
|
//
|
|
65
|
-
//
|
|
66
|
-
// types of input array and temporary buffer)
|
|
67
|
-
// - making vertical pass by horisonltal lines inprove CPU cache use.
|
|
70
|
+
// Notes:
|
|
68
71
|
//
|
|
69
|
-
//
|
|
72
|
+
// - output is transposed
|
|
73
|
+
// - output resolution is ~15 bits per channel(for better precision).
|
|
70
74
|
//
|
|
71
75
|
|
|
72
76
|
|
|
73
|
-
function
|
|
77
|
+
function convolveHor(src, dest, srcW, srcH, destW, filters) {
|
|
74
78
|
var r, g, b, a;
|
|
75
79
|
var filterPtr, filterShift, filterSize;
|
|
76
80
|
var srcPtr, srcY, destX, filterVal;
|
|
@@ -96,39 +100,26 @@ function convolveHorizontally(src, dest, srcW, srcH, destW, filters) {
|
|
|
96
100
|
g = g + filterVal * src[srcPtr + 1] | 0;
|
|
97
101
|
r = r + filterVal * src[srcPtr] | 0;
|
|
98
102
|
srcPtr = srcPtr + 4 | 0;
|
|
99
|
-
} //
|
|
100
|
-
//
|
|
101
|
-
//
|
|
102
|
-
// (!) Add 1/2 of value before clamping to get proper rounding. In other
|
|
103
|
-
// case brightness loss will be noticeable if you resize image with white
|
|
104
|
-
// border and place it on white background.
|
|
103
|
+
} // Store 15 bits between passes for better precision
|
|
104
|
+
// Instead of shift to 14 (FIXED_FRAC_BITS), shift to 7 only
|
|
105
105
|
//
|
|
106
106
|
|
|
107
107
|
|
|
108
|
-
dest[destOffset + 3] =
|
|
109
|
-
|
|
110
|
-
);
|
|
111
|
-
dest[destOffset
|
|
112
|
-
/*FIXED_FRAC_BITS*/
|
|
113
|
-
);
|
|
114
|
-
dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14
|
|
115
|
-
/*FIXED_FRAC_BITS*/
|
|
116
|
-
);
|
|
117
|
-
dest[destOffset] = clampTo8(r + (1 << 13) >> 14
|
|
118
|
-
/*FIXED_FRAC_BITS*/
|
|
119
|
-
);
|
|
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);
|
|
120
112
|
destOffset = destOffset + srcH * 4 | 0;
|
|
121
113
|
}
|
|
122
114
|
|
|
123
115
|
destOffset = (srcY + 1) * 4 | 0;
|
|
124
116
|
srcOffset = (srcY + 1) * srcW * 4 | 0;
|
|
125
117
|
}
|
|
126
|
-
} //
|
|
127
|
-
//
|
|
128
|
-
// keep code in separate functions to avoid deoptimizations & speed loss.
|
|
118
|
+
} // Supplementary method for `convolveHor()`
|
|
119
|
+
//
|
|
129
120
|
|
|
130
121
|
|
|
131
|
-
function
|
|
122
|
+
function convolveVert(src, dest, srcW, srcH, destW, filters) {
|
|
132
123
|
var r, g, b, a;
|
|
133
124
|
var filterPtr, filterShift, filterSize;
|
|
134
125
|
var srcPtr, srcY, destX, filterVal;
|
|
@@ -154,27 +145,134 @@ function convolveVertically(src, dest, srcW, srcH, destW, filters) {
|
|
|
154
145
|
g = g + filterVal * src[srcPtr + 1] | 0;
|
|
155
146
|
r = r + filterVal * src[srcPtr] | 0;
|
|
156
147
|
srcPtr = srcPtr + 4 | 0;
|
|
157
|
-
} //
|
|
158
|
-
|
|
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.
|
|
159
155
|
//
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
|
163
211
|
//
|
|
164
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
|
+
}
|
|
165
219
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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);
|
|
178
276
|
destOffset = destOffset + srcH * 4 | 0;
|
|
179
277
|
}
|
|
180
278
|
|
|
@@ -184,8 +282,10 @@ function convolveVertically(src, dest, srcW, srcH, destW, filters) {
|
|
|
184
282
|
}
|
|
185
283
|
|
|
186
284
|
module.exports = {
|
|
187
|
-
|
|
188
|
-
|
|
285
|
+
convolveHor: convolveHor,
|
|
286
|
+
convolveVert: convolveVert,
|
|
287
|
+
convolveHorWithPre: convolveHorWithPre,
|
|
288
|
+
convolveVertWithPre: convolveVertWithPre
|
|
189
289
|
};
|
|
190
290
|
|
|
191
291
|
},{}],3:[function(_dereq_,module,exports){
|
|
@@ -194,7 +294,7 @@ module.exports = {
|
|
|
194
294
|
'use strict';
|
|
195
295
|
/* eslint-disable max-len */
|
|
196
296
|
|
|
197
|
-
module.exports = '
|
|
297
|
+
module.exports = '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';
|
|
198
298
|
|
|
199
299
|
},{}],4:[function(_dereq_,module,exports){
|
|
200
300
|
'use strict';
|
|
@@ -211,9 +311,23 @@ module.exports = {
|
|
|
211
311
|
|
|
212
312
|
var createFilters = _dereq_('./resize_filter_gen');
|
|
213
313
|
|
|
214
|
-
var
|
|
314
|
+
var _require = _dereq_('./convolve'),
|
|
315
|
+
convolveHor = _require.convolveHor,
|
|
316
|
+
convolveVert = _require.convolveVert,
|
|
317
|
+
convolveHorWithPre = _require.convolveHorWithPre,
|
|
318
|
+
convolveVertWithPre = _require.convolveVertWithPre;
|
|
215
319
|
|
|
216
|
-
|
|
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
|
+
}
|
|
217
331
|
|
|
218
332
|
function resetAlpha(dst, width, height) {
|
|
219
333
|
var ptr = 3,
|
|
@@ -236,20 +350,20 @@ module.exports = function resize(options) {
|
|
|
236
350
|
var offsetX = options.offsetX || 0;
|
|
237
351
|
var offsetY = options.offsetY || 0;
|
|
238
352
|
var dest = options.dest || new Uint8Array(destW * destH * 4);
|
|
239
|
-
var alpha = options.alpha || false;
|
|
240
353
|
var filter = typeof options.filter === 'undefined' ? 'mks2013' : options.filter;
|
|
241
354
|
var filtersX = createFilters(filter, srcW, destW, scaleX, offsetX),
|
|
242
355
|
filtersY = createFilters(filter, srcH, destH, scaleY, offsetY);
|
|
243
|
-
var tmp = new
|
|
244
|
-
// But src can be CanvasPixelArray, and tmp - Uint8Array. So, keep
|
|
245
|
-
// vertical and horizontal passes separately to avoid deoptimization.
|
|
356
|
+
var tmp = new Uint16Array(destW * srcH * 4); // Autodetect if alpha channel exists, and use appropriate method
|
|
246
357
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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
|
+
}
|
|
251
366
|
|
|
252
|
-
if (!alpha) resetAlpha(dest, destW, destH);
|
|
253
367
|
return dest;
|
|
254
368
|
};
|
|
255
369
|
|
|
@@ -473,6 +587,18 @@ module.exports = {
|
|
|
473
587
|
|
|
474
588
|
var createFilters = _dereq_('./resize_filter_gen');
|
|
475
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
|
+
|
|
476
602
|
function resetAlpha(dst, width, height) {
|
|
477
603
|
var ptr = 3,
|
|
478
604
|
len = width * height * 4 | 0;
|
|
@@ -517,16 +643,18 @@ module.exports = function resize_wasm(options) {
|
|
|
517
643
|
var offsetX = options.offsetX || 0.0;
|
|
518
644
|
var offsetY = options.offsetY || 0.0;
|
|
519
645
|
var dest = options.dest || new Uint8Array(destW * destH * 4);
|
|
520
|
-
var alpha = options.alpha || false;
|
|
521
646
|
var filter = typeof options.filter === 'undefined' ? 'mks2013' : options.filter;
|
|
522
647
|
var filtersX = createFilters(filter, srcW, destW, scaleX, offsetX),
|
|
523
648
|
filtersY = createFilters(filter, srcH, destH, scaleY, offsetY); // destination is 0 too.
|
|
524
649
|
|
|
525
|
-
var src_offset = 0;
|
|
650
|
+
var src_offset = 0;
|
|
651
|
+
var src_size = Math.max(src.byteLength, dest.byteLength); // buffer between convolve passes
|
|
526
652
|
|
|
527
|
-
var tmp_offset = this.__align(src_offset +
|
|
653
|
+
var tmp_offset = this.__align(src_offset + src_size);
|
|
528
654
|
|
|
529
|
-
var
|
|
655
|
+
var tmp_size = srcH * destW * 4 * 2; // 2 bytes per channel
|
|
656
|
+
|
|
657
|
+
var filtersX_offset = this.__align(tmp_offset + tmp_size);
|
|
530
658
|
|
|
531
659
|
var filtersY_offset = this.__align(filtersX_offset + filtersX.byteLength);
|
|
532
660
|
|
|
@@ -545,22 +673,24 @@ module.exports = function resize_wasm(options) {
|
|
|
545
673
|
// speed difference is not significant vs direct .set()
|
|
546
674
|
|
|
547
675
|
copyInt16asLE(filtersX, mem, filtersX_offset);
|
|
548
|
-
copyInt16asLE(filtersY, mem, filtersY_offset); //
|
|
549
|
-
// Now call webassembly method
|
|
676
|
+
copyInt16asLE(filtersY, mem, filtersY_offset); // Now call webassembly method
|
|
550
677
|
// emsdk does method names with '_'
|
|
551
678
|
|
|
552
679
|
var fn = instance.exports.convolveHV || instance.exports._convolveHV;
|
|
553
|
-
|
|
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
|
+
} //
|
|
554
687
|
// Copy data back to typed array
|
|
555
688
|
//
|
|
556
689
|
// 32-bit copy is much faster in chrome
|
|
557
690
|
|
|
558
|
-
var dest32 = new Uint32Array(dest.buffer);
|
|
559
|
-
dest32.set(new Uint32Array(this.__memory.buffer, 0, destH * destW)); // That's faster than doing checks in convolver.
|
|
560
|
-
// !!! Note, canvas data is not premultipled. We don't need other
|
|
561
|
-
// alpha corrections.
|
|
562
691
|
|
|
563
|
-
|
|
692
|
+
var dest32 = new Uint32Array(dest.buffer);
|
|
693
|
+
dest32.set(new Uint32Array(this.__memory.buffer, 0, destH * destW));
|
|
564
694
|
return dest;
|
|
565
695
|
};
|
|
566
696
|
|
|
@@ -1149,9 +1279,7 @@ module.exports = function () {
|
|
|
1149
1279
|
|
|
1150
1280
|
if (!tileOpts.src && tileOpts.srcBitmap) {
|
|
1151
1281
|
var canvas = new OffscreenCanvas(tileOpts.width, tileOpts.height);
|
|
1152
|
-
var ctx = canvas.getContext('2d'
|
|
1153
|
-
alpha: Boolean(tileOpts.alpha)
|
|
1154
|
-
});
|
|
1282
|
+
var ctx = canvas.getContext('2d');
|
|
1155
1283
|
ctx.drawImage(tileOpts.srcBitmap, 0, 0);
|
|
1156
1284
|
tileOpts.src = ctx.getImageData(0, 0, tileOpts.width, tileOpts.height).data;
|
|
1157
1285
|
canvas.width = canvas.height = 0;
|
|
@@ -1172,9 +1300,7 @@ module.exports = function () {
|
|
|
1172
1300
|
|
|
1173
1301
|
var _canvas = new OffscreenCanvas(tileOpts.toWidth, tileOpts.toHeight);
|
|
1174
1302
|
|
|
1175
|
-
var _ctx = _canvas.getContext('2d'
|
|
1176
|
-
alpha: Boolean(tileOpts.alpha)
|
|
1177
|
-
});
|
|
1303
|
+
var _ctx = _canvas.getContext('2d');
|
|
1178
1304
|
|
|
1179
1305
|
_ctx.putImageData(toImageData, 0, 0);
|
|
1180
1306
|
|
|
@@ -1313,35 +1439,6 @@ function blurMono16(src, width, height, radius) {
|
|
|
1313
1439
|
module.exports = blurMono16;
|
|
1314
1440
|
|
|
1315
1441
|
},{}],19:[function(_dereq_,module,exports){
|
|
1316
|
-
if (typeof Object.create === 'function') {
|
|
1317
|
-
// implementation from standard node.js 'util' module
|
|
1318
|
-
module.exports = function inherits(ctor, superCtor) {
|
|
1319
|
-
if (superCtor) {
|
|
1320
|
-
ctor.super_ = superCtor
|
|
1321
|
-
ctor.prototype = Object.create(superCtor.prototype, {
|
|
1322
|
-
constructor: {
|
|
1323
|
-
value: ctor,
|
|
1324
|
-
enumerable: false,
|
|
1325
|
-
writable: true,
|
|
1326
|
-
configurable: true
|
|
1327
|
-
}
|
|
1328
|
-
})
|
|
1329
|
-
}
|
|
1330
|
-
};
|
|
1331
|
-
} else {
|
|
1332
|
-
// old school shim for old browsers
|
|
1333
|
-
module.exports = function inherits(ctor, superCtor) {
|
|
1334
|
-
if (superCtor) {
|
|
1335
|
-
ctor.super_ = superCtor
|
|
1336
|
-
var TempCtor = function () {}
|
|
1337
|
-
TempCtor.prototype = superCtor.prototype
|
|
1338
|
-
ctor.prototype = new TempCtor()
|
|
1339
|
-
ctor.prototype.constructor = ctor
|
|
1340
|
-
}
|
|
1341
|
-
}
|
|
1342
|
-
}
|
|
1343
|
-
|
|
1344
|
-
},{}],20:[function(_dereq_,module,exports){
|
|
1345
1442
|
'use strict';
|
|
1346
1443
|
|
|
1347
1444
|
|
|
@@ -1500,7 +1597,7 @@ MultiMath.prototype.__align = function align(number, base) {
|
|
|
1500
1597
|
|
|
1501
1598
|
module.exports = MultiMath;
|
|
1502
1599
|
|
|
1503
|
-
},{"./lib/base64decode":
|
|
1600
|
+
},{"./lib/base64decode":20,"./lib/wa_detect":21,"object-assign":22}],20:[function(_dereq_,module,exports){
|
|
1504
1601
|
// base64 decode str -> Uint8Array, to load WA modules
|
|
1505
1602
|
//
|
|
1506
1603
|
'use strict';
|
|
@@ -1548,7 +1645,7 @@ module.exports = function base64decode(str) {
|
|
|
1548
1645
|
return out;
|
|
1549
1646
|
};
|
|
1550
1647
|
|
|
1551
|
-
},{}],
|
|
1648
|
+
},{}],21:[function(_dereq_,module,exports){
|
|
1552
1649
|
// Detect WebAssembly support.
|
|
1553
1650
|
// - Check global WebAssembly object
|
|
1554
1651
|
// - Try to load simple module (can be disabled via CSP)
|
|
@@ -1587,7 +1684,7 @@ module.exports = function hasWebAssembly() {
|
|
|
1587
1684
|
return wa;
|
|
1588
1685
|
};
|
|
1589
1686
|
|
|
1590
|
-
},{}],
|
|
1687
|
+
},{}],22:[function(_dereq_,module,exports){
|
|
1591
1688
|
/*
|
|
1592
1689
|
object-assign
|
|
1593
1690
|
(c) Sindre Sorhus
|
|
@@ -1679,7 +1776,7 @@ module.exports = shouldUseNative() ? Object.assign : function (target, source) {
|
|
|
1679
1776
|
return to;
|
|
1680
1777
|
};
|
|
1681
1778
|
|
|
1682
|
-
},{}],
|
|
1779
|
+
},{}],23:[function(_dereq_,module,exports){
|
|
1683
1780
|
var bundleFn = arguments[3];
|
|
1684
1781
|
var sources = arguments[4];
|
|
1685
1782
|
var cache = arguments[5];
|
|
@@ -1825,7 +1922,6 @@ var DEFAULT_PICA_OPTS = {
|
|
|
1825
1922
|
};
|
|
1826
1923
|
var DEFAULT_RESIZE_OPTS = {
|
|
1827
1924
|
filter: 'mks2013',
|
|
1828
|
-
alpha: false,
|
|
1829
1925
|
unsharpAmount: 0,
|
|
1830
1926
|
unsharpRadius: 0.0,
|
|
1831
1927
|
unsharpThreshold: 0
|
|
@@ -2044,9 +2140,7 @@ Pica.prototype.__extractTileData = function (tile, from, opts, stageEnv, extract
|
|
|
2044
2140
|
|
|
2045
2141
|
|
|
2046
2142
|
if (utils.isCanvas(from)) {
|
|
2047
|
-
if (!stageEnv.srcCtx) stageEnv.srcCtx = from.getContext('2d'
|
|
2048
|
-
alpha: Boolean(opts.alpha)
|
|
2049
|
-
}); // If input is Canvas - extract region data directly
|
|
2143
|
+
if (!stageEnv.srcCtx) stageEnv.srcCtx = from.getContext('2d'); // If input is Canvas - extract region data directly
|
|
2050
2144
|
|
|
2051
2145
|
this.debug('Get tile pixel data');
|
|
2052
2146
|
extractTo.src = stageEnv.srcCtx.getImageData(tile.x, tile.y, tile.width, tile.height).data;
|
|
@@ -2060,9 +2154,7 @@ Pica.prototype.__extractTileData = function (tile, from, opts, stageEnv, extract
|
|
|
2060
2154
|
|
|
2061
2155
|
this.debug('Draw tile imageBitmap/image to temporary canvas');
|
|
2062
2156
|
var tmpCanvas = this.options.createCanvas(tile.width, tile.height);
|
|
2063
|
-
var tmpCtx = tmpCanvas.getContext('2d'
|
|
2064
|
-
alpha: Boolean(opts.alpha)
|
|
2065
|
-
});
|
|
2157
|
+
var tmpCtx = tmpCanvas.getContext('2d');
|
|
2066
2158
|
tmpCtx.globalCompositeOperation = 'copy';
|
|
2067
2159
|
tmpCtx.drawImage(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height, 0, 0, tile.width, tile.height);
|
|
2068
2160
|
this.debug('Get tile pixel data');
|
|
@@ -2136,7 +2228,6 @@ Pica.prototype.__tileAndResize = function (from, to, opts) {
|
|
|
2136
2228
|
offsetX: tile.offsetX,
|
|
2137
2229
|
offsetY: tile.offsetY,
|
|
2138
2230
|
filter: opts.filter,
|
|
2139
|
-
alpha: opts.alpha,
|
|
2140
2231
|
unsharpAmount: opts.unsharpAmount,
|
|
2141
2232
|
unsharpRadius: opts.unsharpRadius,
|
|
2142
2233
|
unsharpThreshold: opts.unsharpThreshold
|
|
@@ -2161,9 +2252,7 @@ Pica.prototype.__tileAndResize = function (from, to, opts) {
|
|
|
2161
2252
|
|
|
2162
2253
|
|
|
2163
2254
|
return Promise.resolve().then(function () {
|
|
2164
|
-
stageEnv.toCtx = to.getContext('2d'
|
|
2165
|
-
alpha: Boolean(opts.alpha)
|
|
2166
|
-
});
|
|
2255
|
+
stageEnv.toCtx = to.getContext('2d');
|
|
2167
2256
|
if (utils.isCanvas(from)) return null;
|
|
2168
2257
|
|
|
2169
2258
|
if (utils.isImageBitmap(from)) {
|
|
@@ -2284,9 +2373,7 @@ Pica.prototype.__processStages = function (stages, from, to, opts) {
|
|
|
2284
2373
|
Pica.prototype.__resizeViaCreateImageBitmap = function (from, to, opts) {
|
|
2285
2374
|
var _this5 = this;
|
|
2286
2375
|
|
|
2287
|
-
var toCtx = to.getContext('2d'
|
|
2288
|
-
alpha: Boolean(opts.alpha)
|
|
2289
|
-
});
|
|
2376
|
+
var toCtx = to.getContext('2d');
|
|
2290
2377
|
this.debug('Resize via createImageBitmap()');
|
|
2291
2378
|
return createImageBitmap(from, {
|
|
2292
2379
|
resizeWidth: opts.toWidth,
|
|
@@ -2309,9 +2396,7 @@ Pica.prototype.__resizeViaCreateImageBitmap = function (from, to, opts) {
|
|
|
2309
2396
|
|
|
2310
2397
|
var tmpCanvas = _this5.options.createCanvas(opts.toWidth, opts.toHeight);
|
|
2311
2398
|
|
|
2312
|
-
var tmpCtx = tmpCanvas.getContext('2d'
|
|
2313
|
-
alpha: Boolean(opts.alpha)
|
|
2314
|
-
});
|
|
2399
|
+
var tmpCtx = tmpCanvas.getContext('2d');
|
|
2315
2400
|
tmpCtx.drawImage(imageBitmap, 0, 0);
|
|
2316
2401
|
imageBitmap.close();
|
|
2317
2402
|
var iData = tmpCtx.getImageData(0, 0, opts.toWidth, opts.toHeight);
|
|
@@ -2461,5 +2546,5 @@ Pica.prototype.debug = function () {};
|
|
|
2461
2546
|
|
|
2462
2547
|
module.exports = Pica;
|
|
2463
2548
|
|
|
2464
|
-
},{"./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":
|
|
2549
|
+
},{"./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")
|
|
2465
2550
|
});
|