Add files
This commit is contained in:
commit
bb80829159
18195 changed files with 2122994 additions and 0 deletions
77
509bba0_unpacked_with_node_modules/~/pica/lib/pure/blur.js
generated
Executable file
77
509bba0_unpacked_with_node_modules/~/pica/lib/pure/blur.js
generated
Executable file
|
@ -0,0 +1,77 @@
|
|||
// Blur filter
|
||||
//
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
var _blurKernel = new Uint8Array([
|
||||
1, 2, 1,
|
||||
2, 4, 2,
|
||||
1, 2, 1
|
||||
]);
|
||||
|
||||
var _bkWidth = Math.floor(Math.sqrt(_blurKernel.length));
|
||||
var _bkHalf = Math.floor(_bkWidth / 2);
|
||||
var _bkWsum = 0;
|
||||
for (var wc=0; wc < _blurKernel.length; wc++) { _bkWsum += _blurKernel[wc]; }
|
||||
|
||||
|
||||
function blurPoint(gs, x, y, srcW, srcH) {
|
||||
var bx, by, sx, sy, w, wsum, br;
|
||||
var bPtr = 0;
|
||||
var blurKernel = _blurKernel;
|
||||
var bkHalf = _bkHalf;
|
||||
|
||||
wsum = 0; // weight sum to normalize result
|
||||
br = 0;
|
||||
|
||||
if (x >= bkHalf && y >= bkHalf && x + bkHalf < srcW && y + bkHalf < srcH) {
|
||||
for (by = 0; by < 3; by++) {
|
||||
for (bx = 0; bx < 3; bx++) {
|
||||
sx = x + bx - bkHalf;
|
||||
sy = y + by - bkHalf;
|
||||
|
||||
br += gs[sx + sy * srcW] * blurKernel[bPtr++];
|
||||
}
|
||||
}
|
||||
return (br - (br % _bkWsum)) / _bkWsum;
|
||||
}
|
||||
|
||||
for (by = 0; by < 3; by++) {
|
||||
for (bx = 0; bx < 3; bx++) {
|
||||
sx = x + bx - bkHalf;
|
||||
sy = y + by - bkHalf;
|
||||
|
||||
if (sx >= 0 && sx < srcW && sy >= 0 && sy < srcH) {
|
||||
w = blurKernel[bPtr];
|
||||
wsum += w;
|
||||
br += gs[sx + sy * srcW] * w;
|
||||
}
|
||||
bPtr++;
|
||||
}
|
||||
}
|
||||
return ((br - (br % wsum)) / wsum)|0;
|
||||
}
|
||||
|
||||
function blur(src, srcW, srcH/*, radius*/) {
|
||||
var x, y,
|
||||
output = new Uint16Array(src.length);
|
||||
|
||||
for (x = 0; x < srcW; x++) {
|
||||
for (y = 0; y < srcH; y++) {
|
||||
output[y * srcW + x] = blurPoint(src, x, y, srcW, srcH);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
module.exports = blur;
|
||||
|
||||
|
||||
|
||||
//////////////////
|
||||
// WEBPACK FOOTER
|
||||
// ./~/pica/lib/pure/blur.js
|
||||
// module id = 2632
|
||||
// module chunks = 4
|
323
509bba0_unpacked_with_node_modules/~/pica/lib/pure/resize.js
generated
Executable file
323
509bba0_unpacked_with_node_modules/~/pica/lib/pure/resize.js
generated
Executable file
|
@ -0,0 +1,323 @@
|
|||
// High speed resize with tuneable speed/quality ratio
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
var unsharp = require('./unsharp');
|
||||
|
||||
|
||||
// Precision of fixed FP values
|
||||
var FIXED_FRAC_BITS = 14;
|
||||
var FIXED_FRAC_VAL = 1 << FIXED_FRAC_BITS;
|
||||
|
||||
|
||||
//
|
||||
// Presets for quality 0..3. Filter functions + window size
|
||||
//
|
||||
var FILTER_INFO = [
|
||||
{ // Nearest neibor (Box)
|
||||
win: 0.5,
|
||||
filter: function (x) {
|
||||
return (x >= -0.5 && x < 0.5) ? 1.0 : 0.0;
|
||||
}
|
||||
},
|
||||
{ // Hamming
|
||||
win: 1.0,
|
||||
filter: function (x) {
|
||||
if (x <= -1.0 || x >= 1.0) { return 0.0; }
|
||||
if (x > -1.19209290E-07 && x < 1.19209290E-07) { return 1.0; }
|
||||
var xpi = x * Math.PI;
|
||||
return ((Math.sin(xpi) / xpi) * (0.54 + 0.46 * Math.cos(xpi / 1.0)));
|
||||
}
|
||||
},
|
||||
{ // Lanczos, win = 2
|
||||
win: 2.0,
|
||||
filter: function (x) {
|
||||
if (x <= -2.0 || x >= 2.0) { return 0.0; }
|
||||
if (x > -1.19209290E-07 && x < 1.19209290E-07) { return 1.0; }
|
||||
var xpi = x * Math.PI;
|
||||
return (Math.sin(xpi) / xpi) * Math.sin(xpi / 2.0) / (xpi / 2.0);
|
||||
}
|
||||
},
|
||||
{ // Lanczos, win = 3
|
||||
win: 3.0,
|
||||
filter: function (x) {
|
||||
if (x <= -3.0 || x >= 3.0) { return 0.0; }
|
||||
if (x > -1.19209290E-07 && x < 1.19209290E-07) { return 1.0; }
|
||||
var xpi = x * Math.PI;
|
||||
return (Math.sin(xpi) / xpi) * Math.sin(xpi / 3.0) / (xpi / 3.0);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
function clampTo8(i) { return i < 0 ? 0 : (i > 255 ? 255 : i); }
|
||||
|
||||
function toFixedPoint(num) { return Math.floor(num * FIXED_FRAC_VAL); }
|
||||
|
||||
|
||||
// Calculate convolution filters for each destination point,
|
||||
// and pack data to Int16Array:
|
||||
//
|
||||
// [ shift, length, data..., shift2, length2, data..., ... ]
|
||||
//
|
||||
// - shift - offset in src image
|
||||
// - length - filter length (in src points)
|
||||
// - data - filter values sequence
|
||||
//
|
||||
function createFilters(quality, srcSize, destSize) {
|
||||
|
||||
var filterFunction = FILTER_INFO[quality].filter;
|
||||
|
||||
var scale = destSize / srcSize;
|
||||
var scaleInverted = 1.0 / scale;
|
||||
var scaleClamped = Math.min(1.0, scale); // For upscale
|
||||
|
||||
// Filter window (averaging interval), scaled to src image
|
||||
var srcWindow = FILTER_INFO[quality].win / scaleClamped;
|
||||
|
||||
var destPixel, srcPixel, srcFirst, srcLast, filterElementSize,
|
||||
floatFilter, fxpFilter, total, fixedTotal, pxl, idx, floatVal, fixedVal;
|
||||
var leftNotEmpty, rightNotEmpty, filterShift, filterSize;
|
||||
|
||||
var maxFilterElementSize = Math.floor((srcWindow + 1) * 2 );
|
||||
var packedFilter = new Int16Array((maxFilterElementSize + 2) * destSize);
|
||||
var packedFilterPtr = 0;
|
||||
|
||||
// For each destination pixel calculate source range and built filter values
|
||||
for (destPixel = 0; destPixel < destSize; destPixel++) {
|
||||
|
||||
// Scaling should be done relative to central pixel point
|
||||
srcPixel = (destPixel + 0.5) * scaleInverted;
|
||||
|
||||
srcFirst = Math.max(0, Math.floor(srcPixel - srcWindow));
|
||||
srcLast = Math.min(srcSize - 1, Math.ceil(srcPixel + srcWindow));
|
||||
|
||||
filterElementSize = srcLast - srcFirst + 1;
|
||||
floatFilter = new Float32Array(filterElementSize);
|
||||
fxpFilter = new Int16Array(filterElementSize);
|
||||
|
||||
total = 0.0;
|
||||
|
||||
// Fill filter values for calculated range
|
||||
for (pxl = srcFirst, idx = 0; pxl <= srcLast; pxl++, idx++) {
|
||||
floatVal = filterFunction(((pxl + 0.5) - srcPixel) * scaleClamped);
|
||||
total += floatVal;
|
||||
floatFilter[idx] = floatVal;
|
||||
}
|
||||
|
||||
// Normalize filter, convert to fixed point and accumulate conversion error
|
||||
fixedTotal = 0;
|
||||
|
||||
for (idx = 0; idx < floatFilter.length; idx++) {
|
||||
fixedVal = toFixedPoint(floatFilter[idx] / total);
|
||||
fixedTotal += fixedVal;
|
||||
fxpFilter[idx] = fixedVal;
|
||||
}
|
||||
|
||||
// Compensate normalization error, to minimize brightness drift
|
||||
fxpFilter[destSize >> 1] += toFixedPoint(1.0) - fixedTotal;
|
||||
|
||||
//
|
||||
// Now pack filter to useable form
|
||||
//
|
||||
// 1. Trim heading and tailing zero values, and compensate shitf/length
|
||||
// 2. Put all to single array in this format:
|
||||
//
|
||||
// [ pos shift, data length, value1, value2, value3, ... ]
|
||||
//
|
||||
|
||||
leftNotEmpty = 0;
|
||||
while (leftNotEmpty < fxpFilter.length && fxpFilter[leftNotEmpty] === 0) {
|
||||
leftNotEmpty++;
|
||||
}
|
||||
|
||||
if (leftNotEmpty < fxpFilter.length) {
|
||||
rightNotEmpty = fxpFilter.length - 1;
|
||||
while (rightNotEmpty > 0 && fxpFilter[rightNotEmpty] === 0) {
|
||||
rightNotEmpty--;
|
||||
}
|
||||
|
||||
filterShift = srcFirst + leftNotEmpty;
|
||||
filterSize = rightNotEmpty - leftNotEmpty + 1;
|
||||
|
||||
packedFilter[packedFilterPtr++] = filterShift; // shift
|
||||
packedFilter[packedFilterPtr++] = filterSize; // size
|
||||
|
||||
packedFilter.set(fxpFilter.subarray(leftNotEmpty, rightNotEmpty + 1), packedFilterPtr);
|
||||
packedFilterPtr += filterSize;
|
||||
} else {
|
||||
// zero data, write header only
|
||||
packedFilter[packedFilterPtr++] = 0; // shift
|
||||
packedFilter[packedFilterPtr++] = 0; // size
|
||||
}
|
||||
}
|
||||
return packedFilter;
|
||||
}
|
||||
|
||||
// Convolve image in horizontal directions and transpose output. In theory,
|
||||
// transpose allow:
|
||||
//
|
||||
// - use the same convolver for both passes (this fails due different
|
||||
// types of input array and temporary buffer)
|
||||
// - making vertical pass by horisonltal lines inprove CPU cache use.
|
||||
//
|
||||
// But in real life this doesn't work :)
|
||||
//
|
||||
function convolveHorizontally(src, dest, srcW, srcH, destW, filters) {
|
||||
|
||||
var r, g, b, a;
|
||||
var filterPtr, filterShift, filterSize;
|
||||
var srcPtr, srcY, destX, filterVal;
|
||||
var srcOffset = 0, destOffset = 0;
|
||||
|
||||
// For each row
|
||||
for (srcY = 0; srcY < srcH; srcY++) {
|
||||
filterPtr = 0;
|
||||
|
||||
// Apply precomputed filters to each destination row point
|
||||
for (destX = 0; destX < destW; destX++) {
|
||||
// Get the filter that determines the current output pixel.
|
||||
filterShift = filters[filterPtr++];
|
||||
filterSize = filters[filterPtr++];
|
||||
|
||||
srcPtr = (srcOffset + (filterShift * 4))|0;
|
||||
|
||||
r = g = b = a = 0;
|
||||
|
||||
// Apply the filter to the row to get the destination pixel r, g, b, a
|
||||
for (; filterSize > 0; filterSize--) {
|
||||
filterVal = filters[filterPtr++];
|
||||
|
||||
// Use reverse order to workaround deopts in old v8 (node v.10)
|
||||
// Big thanks to @mraleph (Vyacheslav Egorov) for the tip.
|
||||
a = (a + filterVal * src[srcPtr + 3])|0;
|
||||
b = (b + filterVal * src[srcPtr + 2])|0;
|
||||
g = (g + filterVal * src[srcPtr + 1])|0;
|
||||
r = (r + filterVal * src[srcPtr])|0;
|
||||
srcPtr = (srcPtr + 4)|0;
|
||||
}
|
||||
|
||||
// Bring this value back in range. All of the filter scaling factors
|
||||
// are in fixed point with FIXED_FRAC_BITS bits of fractional part.
|
||||
dest[destOffset + 3] = clampTo8(a >> 14/*FIXED_FRAC_BITS*/);
|
||||
dest[destOffset + 2] = clampTo8(b >> 14/*FIXED_FRAC_BITS*/);
|
||||
dest[destOffset + 1] = clampTo8(g >> 14/*FIXED_FRAC_BITS*/);
|
||||
dest[destOffset] = clampTo8(r >> 14/*FIXED_FRAC_BITS*/);
|
||||
destOffset = (destOffset + srcH * 4)|0;
|
||||
}
|
||||
|
||||
destOffset = ((srcY + 1) * 4)|0;
|
||||
srcOffset = ((srcY + 1) * srcW * 4)|0;
|
||||
}
|
||||
}
|
||||
|
||||
// Technically, convolvers are the same. But input array and temporary
|
||||
// buffer can be of different type (especially, in old browsers). So,
|
||||
// keep code in separate functions to avoid deoptimizations & speed loss.
|
||||
|
||||
function convolveVertically(src, dest, srcW, srcH, destW, filters) {
|
||||
|
||||
var r, g, b, a;
|
||||
var filterPtr, filterShift, filterSize;
|
||||
var srcPtr, srcY, destX, filterVal;
|
||||
var srcOffset = 0, destOffset = 0;
|
||||
|
||||
// For each row
|
||||
for (srcY = 0; srcY < srcH; srcY++) {
|
||||
filterPtr = 0;
|
||||
|
||||
// Apply precomputed filters to each destination row point
|
||||
for (destX = 0; destX < destW; destX++) {
|
||||
// Get the filter that determines the current output pixel.
|
||||
filterShift = filters[filterPtr++];
|
||||
filterSize = filters[filterPtr++];
|
||||
|
||||
srcPtr = (srcOffset + (filterShift * 4))|0;
|
||||
|
||||
r = g = b = a = 0;
|
||||
|
||||
// Apply the filter to the row to get the destination pixel r, g, b, a
|
||||
for (; filterSize > 0; filterSize--) {
|
||||
filterVal = filters[filterPtr++];
|
||||
|
||||
// Use reverse order to workaround deopts in old v8 (node v.10)
|
||||
// Big thanks to @mraleph (Vyacheslav Egorov) for the tip.
|
||||
a = (a + filterVal * src[srcPtr + 3])|0;
|
||||
b = (b + filterVal * src[srcPtr + 2])|0;
|
||||
g = (g + filterVal * src[srcPtr + 1])|0;
|
||||
r = (r + filterVal * src[srcPtr])|0;
|
||||
srcPtr = (srcPtr + 4)|0;
|
||||
}
|
||||
|
||||
// Bring this value back in range. All of the filter scaling factors
|
||||
// are in fixed point with FIXED_FRAC_BITS bits of fractional part.
|
||||
dest[destOffset + 3] = clampTo8(a >> 14/*FIXED_FRAC_BITS*/);
|
||||
dest[destOffset + 2] = clampTo8(b >> 14/*FIXED_FRAC_BITS*/);
|
||||
dest[destOffset + 1] = clampTo8(g >> 14/*FIXED_FRAC_BITS*/);
|
||||
dest[destOffset] = clampTo8(r >> 14/*FIXED_FRAC_BITS*/);
|
||||
destOffset = (destOffset + srcH * 4)|0;
|
||||
}
|
||||
|
||||
destOffset = ((srcY + 1) * 4)|0;
|
||||
srcOffset = ((srcY + 1) * srcW * 4)|0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function resetAlpha(dst, width, height) {
|
||||
var ptr = 3, len = (width * height * 4)|0;
|
||||
while (ptr < len) { dst[ptr] = 0xFF; ptr = (ptr + 4)|0; }
|
||||
}
|
||||
|
||||
|
||||
function resize(options) {
|
||||
var src = options.src;
|
||||
var srcW = options.width;
|
||||
var srcH = options.height;
|
||||
var destW = options.toWidth;
|
||||
var destH = options.toHeight;
|
||||
var dest = options.dest || new Uint8Array(destW * destH * 4);
|
||||
var quality = options.quality === undefined ? 3 : options.quality;
|
||||
var alpha = options.alpha || false;
|
||||
var unsharpAmount = options.unsharpAmount === undefined ? 0 : (options.unsharpAmount|0);
|
||||
var unsharpThreshold = options.unsharpThreshold === undefined ? 0 : (options.unsharpThreshold|0);
|
||||
|
||||
if (srcW < 1 || srcH < 1 || destW < 1 || destH < 1) { return []; }
|
||||
|
||||
var filtersX = createFilters(quality, srcW, destW),
|
||||
filtersY = createFilters(quality, srcH, destH);
|
||||
|
||||
var tmp = new Uint8Array(destW * srcH * 4);
|
||||
|
||||
// To use single function we need src & tmp of the same type.
|
||||
// But src can be CanvasPixelArray, and tmp - Uint8Array. So, keep
|
||||
// vertical and horizontal passes separately to avoid deoptimization.
|
||||
|
||||
convolveHorizontally(src, tmp, srcW, srcH, destW, filtersX);
|
||||
convolveVertically(tmp, dest, srcH, destW, destH, filtersY);
|
||||
|
||||
// That's faster than doing checks in convolver.
|
||||
// !!! Note, canvas data is not premultipled. We don't need other
|
||||
// alpha corrections.
|
||||
|
||||
if (!alpha) {
|
||||
resetAlpha(dest, destW, destH);
|
||||
}
|
||||
|
||||
if (unsharpAmount) {
|
||||
unsharp(dest, destW, destH, unsharpAmount, 1.0, unsharpThreshold);
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
module.exports = resize;
|
||||
|
||||
|
||||
|
||||
//////////////////
|
||||
// WEBPACK FOOTER
|
||||
// ./~/pica/lib/pure/resize.js
|
||||
// module id = 2633
|
||||
// module chunks = 4
|
97
509bba0_unpacked_with_node_modules/~/pica/lib/pure/unsharp.js
generated
Executable file
97
509bba0_unpacked_with_node_modules/~/pica/lib/pure/unsharp.js
generated
Executable file
|
@ -0,0 +1,97 @@
|
|||
// Unsharp mask filter
|
||||
//
|
||||
// http://stackoverflow.com/a/23322820/1031804
|
||||
// USM(O) = O + (2 * (Amount / 100) * (O - GB))
|
||||
// GB - gaussial blur.
|
||||
//
|
||||
// brightness = 0.299*R + 0.587*G + 0.114*B
|
||||
// http://stackoverflow.com/a/596243/1031804
|
||||
//
|
||||
// To simplify math, normalize brighness mutipliers to 2^16:
|
||||
//
|
||||
// brightness = (19595*R + 38470*G + 7471*B) / 65536
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
var blur = require('./blur');
|
||||
|
||||
|
||||
function clampTo8(i) { return i < 0 ? 0 : (i > 255 ? 255 : i); }
|
||||
|
||||
// Convert image to greyscale, 16bits FP result (8.8)
|
||||
//
|
||||
function greyscale(src, srcW, srcH) {
|
||||
var size = srcW * srcH;
|
||||
var result = new Uint16Array(size); // We don't use sign, but that helps to JIT
|
||||
var i, srcPtr;
|
||||
|
||||
for (i = 0, srcPtr = 0; i < size; i++) {
|
||||
result[i] = (src[srcPtr + 2] * 7471 // blue
|
||||
+ src[srcPtr + 1] * 38470 // green
|
||||
+ src[srcPtr] * 19595) >>> 8; // red
|
||||
srcPtr = (srcPtr + 4)|0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Apply unsharp mask to src
|
||||
//
|
||||
// NOTE: radius is ignored to simplify gaussian blur calculation
|
||||
// on practice we need radius 0.3..2.0. Use 1.0 now.
|
||||
//
|
||||
function unsharp(src, srcW, srcH, amount, radius, threshold) {
|
||||
var x, y, c, diff = 0, corr, srcPtr;
|
||||
|
||||
// Normalized delta multiplier. Expect that:
|
||||
var AMOUNT_NORM = Math.floor(amount * 256 / 50);
|
||||
|
||||
// Convert to grayscale:
|
||||
//
|
||||
// - prevent color drift
|
||||
// - speedup blur calc
|
||||
//
|
||||
var gs = greyscale(src, srcW, srcH);
|
||||
var blured = blur(gs, srcW, srcH, 1);
|
||||
var fpThreshold = threshold << 8;
|
||||
var gsPtr = 0;
|
||||
|
||||
for (y = 0; y < srcH; y++) {
|
||||
for (x = 0; x < srcW; x++) {
|
||||
|
||||
// calculate brightness blur, difference & update source buffer
|
||||
|
||||
diff = gs[gsPtr] - blured[gsPtr];
|
||||
|
||||
// Update source image if thresold exceeded
|
||||
if (Math.abs(diff) > fpThreshold) {
|
||||
// Calculate correction multiplier
|
||||
corr = 65536 + ((diff * AMOUNT_NORM) >> 8);
|
||||
srcPtr = gsPtr * 4;
|
||||
|
||||
c = src[srcPtr];
|
||||
src[srcPtr++] = clampTo8((c * corr) >> 16);
|
||||
c = src[srcPtr];
|
||||
src[srcPtr++] = clampTo8((c * corr) >> 16);
|
||||
c = src[srcPtr];
|
||||
src[srcPtr] = clampTo8((c * corr) >> 16);
|
||||
}
|
||||
|
||||
gsPtr++;
|
||||
|
||||
} // end row
|
||||
} // end column
|
||||
}
|
||||
|
||||
|
||||
module.exports = unsharp;
|
||||
|
||||
|
||||
|
||||
//////////////////
|
||||
// WEBPACK FOOTER
|
||||
// ./~/pica/lib/pure/unsharp.js
|
||||
// module id = 2634
|
||||
// module chunks = 4
|
18
509bba0_unpacked_with_node_modules/~/pica/lib/resize.js
generated
Executable file
18
509bba0_unpacked_with_node_modules/~/pica/lib/resize.js
generated
Executable file
|
@ -0,0 +1,18 @@
|
|||
// Proxy to simplify split between webworker/plain calls
|
||||
'use strict';
|
||||
|
||||
var resize = require('./pure/resize');
|
||||
|
||||
module.exports = function (options, callback) {
|
||||
var output = resize(options);
|
||||
|
||||
callback(null, output);
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////
|
||||
// WEBPACK FOOTER
|
||||
// ./~/pica/lib/resize.js
|
||||
// module id = 630
|
||||
// module chunks = 4
|
26
509bba0_unpacked_with_node_modules/~/pica/lib/resize_worker.js
generated
Executable file
26
509bba0_unpacked_with_node_modules/~/pica/lib/resize_worker.js
generated
Executable file
|
@ -0,0 +1,26 @@
|
|||
// Web Worker wrapper for image resize function
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function(self) {
|
||||
var resize = require('./resize');
|
||||
|
||||
self.onmessage = function (ev) {
|
||||
resize(ev.data, function(err, output) {
|
||||
if (err) {
|
||||
self.postMessage({ err: err });
|
||||
return;
|
||||
}
|
||||
|
||||
self.postMessage({ output: output }, [ output.buffer ]);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////
|
||||
// WEBPACK FOOTER
|
||||
// ./~/pica/lib/resize_worker.js
|
||||
// module id = 2635
|
||||
// module chunks = 4
|
Loading…
Add table
Add a link
Reference in a new issue