Path: blob/master/node_modules/@jimp/plugin-blur/src/index.js
1126 views
import { throwError, isNodePattern } from '@jimp/utils';1import { mulTable, shgTable } from './blur-tables';23/*4Superfast Blur (0.5)5http://www.quasimondo.com/BoxBlurForCanvas/FastBlur.js67Copyright (c) 2011 Mario Klingemann89Permission is hereby granted, free of charge, to any person10obtaining a copy of this software and associated documentation11files (the "Software"), to deal in the Software without12restriction, including without limitation the rights to use,13copy, modify, merge, publish, distribute, sublicense, and/or sell14copies of the Software, and to permit persons to whom the15Software is furnished to do so, subject to the following16conditions:1718The above copyright notice and this permission notice shall be19included in all copies or substantial portions of the Software.2021THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,22EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES23OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND24NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT25HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,26WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING27FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR28OTHER DEALINGS IN THE SOFTWARE.29*/3031export default () => ({32/**33* A fast blur algorithm that produces similar effect to a Gaussian blur - but MUCH quicker34* @param {number} r the pixel radius of the blur35* @param {function(Error, Jimp)} cb (optional) a callback for when complete36* @returns {Jimp} this for chaining of methods37*/38blur(r, cb) {39if (typeof r !== 'number')40return throwError.call(this, 'r must be a number', cb);41if (r < 1) return throwError.call(this, 'r must be greater than 0', cb);4243let rsum;44let gsum;45let bsum;46let asum;47let x;48let y;49let i;50let p;51let p1;52let p2;53let yp;54let yi;55let yw;56let pa;5758const wm = this.bitmap.width - 1;59const hm = this.bitmap.height - 1;60// const wh = this.bitmap.width * this.bitmap.height;61const rad1 = r + 1;6263const mulSum = mulTable[r];64const shgSum = shgTable[r];6566const red = [];67const green = [];68const blue = [];69const alpha = [];7071const vmin = [];72const vmax = [];7374let iterations = 2;7576while (iterations-- > 0) {77yi = 0;78yw = 0;7980for (y = 0; y < this.bitmap.height; y++) {81rsum = this.bitmap.data[yw] * rad1;82gsum = this.bitmap.data[yw + 1] * rad1;83bsum = this.bitmap.data[yw + 2] * rad1;84asum = this.bitmap.data[yw + 3] * rad1;8586for (i = 1; i <= r; i++) {87p = yw + ((i > wm ? wm : i) << 2);88rsum += this.bitmap.data[p++];89gsum += this.bitmap.data[p++];90bsum += this.bitmap.data[p++];91asum += this.bitmap.data[p];92}9394for (x = 0; x < this.bitmap.width; x++) {95red[yi] = rsum;96green[yi] = gsum;97blue[yi] = bsum;98alpha[yi] = asum;99100if (y === 0) {101vmin[x] = ((p = x + rad1) < wm ? p : wm) << 2;102vmax[x] = (p = x - r) > 0 ? p << 2 : 0;103}104105p1 = yw + vmin[x];106p2 = yw + vmax[x];107108rsum += this.bitmap.data[p1++] - this.bitmap.data[p2++];109gsum += this.bitmap.data[p1++] - this.bitmap.data[p2++];110bsum += this.bitmap.data[p1++] - this.bitmap.data[p2++];111asum += this.bitmap.data[p1] - this.bitmap.data[p2];112113yi++;114}115116yw += this.bitmap.width << 2;117}118119for (x = 0; x < this.bitmap.width; x++) {120yp = x;121rsum = red[yp] * rad1;122gsum = green[yp] * rad1;123bsum = blue[yp] * rad1;124asum = alpha[yp] * rad1;125126for (i = 1; i <= r; i++) {127yp += i > hm ? 0 : this.bitmap.width;128rsum += red[yp];129gsum += green[yp];130bsum += blue[yp];131asum += alpha[yp];132}133134yi = x << 2;135136for (y = 0; y < this.bitmap.height; y++) {137pa = (asum * mulSum) >>> shgSum;138this.bitmap.data[yi + 3] = pa;139140// normalize alpha141if (pa > 255) {142this.bitmap.data[yi + 3] = 255;143}144145if (pa > 0) {146pa = 255 / pa;147this.bitmap.data[yi] = ((rsum * mulSum) >>> shgSum) * pa;148this.bitmap.data[yi + 1] = ((gsum * mulSum) >>> shgSum) * pa;149this.bitmap.data[yi + 2] = ((bsum * mulSum) >>> shgSum) * pa;150} else {151this.bitmap.data[yi + 2] = 0;152this.bitmap.data[yi + 1] = 0;153this.bitmap.data[yi] = 0;154}155156if (x === 0) {157vmin[y] = ((p = y + rad1) < hm ? p : hm) * this.bitmap.width;158vmax[y] = (p = y - r) > 0 ? p * this.bitmap.width : 0;159}160161p1 = x + vmin[y];162p2 = x + vmax[y];163164rsum += red[p1] - red[p2];165gsum += green[p1] - green[p2];166bsum += blue[p1] - blue[p2];167asum += alpha[p1] - alpha[p2];168169yi += this.bitmap.width << 2;170}171}172}173174if (isNodePattern(cb)) {175cb.call(this, null, this);176}177178return this;179}180});181182183