/* eslint-disable */ const HAS_ALPHA = true function scale(scale, input, output, inputRemovable) { if (!input) { input = scale.input output = scale.output inputRemovable = scale.inputRemovable if (scale.scale) scale = scale.scale } var canvas, ctx if (input.src) { canvas = document.createElement('canvas') if (input.naturalWidth != null) { canvas.width = input.naturalWidth canvas.height = input.naturalHeight } else if (input.runtimeStyle != null) { var runtimeStyle = input.runtimeStyle , mw = runtimeStyle.width, mh = runtimeStyle.height runtimeStyle.width = 'auto' runtimeStyle.height = 'auto' canvas.width = input.width canvas.height = input.height runtimeStyle.width = mw runtimeStyle.height = mh } else { var mw = input.width, mh = input.height if (input.removeAttribute) { input.removeAttribute('width') input.removeAttribute('height') } canvas.width = input.width canvas.height = input.height input.width = mw input.height = mh } } else { canvas = input } ctx = canvas.getContext('2d') if (input.src) ctx.drawImage(input, 0, 0) var sw = canvas.width, sh = canvas.height , dw, dh , sourceBuffer = ctx.getImageData(0, 0, sw, sh).data if (!sw || !sh) return false if (input.src || inputRemovable) { ctx.clearRect(0, 0, sw, sh) } if (typeof scale === 'object') { if (scale.width) { dw = scale.width + 0.5 | 0 dh = scale.height + 0.5 | 0 } else { dw = sw * scale.scaleX + 0.5 | 0 dh = sh * scale.scaleY + 0.5 | 0 } } else { dw = scale * sw + 0.5 | 0 dh = scale * sh + 0.5 | 0 } var dw4 = dw << 2 , sw4 = sw << 2 , sx, sy, sindex = 0 , dx, dy, dyindex, dindex = 0 , idx, idy, isx, isy , w, wx, nwx, wy, nwy , crossX, crossY , dwh4 = dw4 * dh , tmpBuffer , r, g, b, a , dsy, dsx , newCanvas, newCtx, imageData, byteBuffer , TIMES = 255.99 / 255 , row0, row1, row2, row3 , col0, col1, col2, col3 , scaleX = dw / sw , scaleY = dh / sh , scaleXY = scaleX * scaleY function setNewCanvas() { // CREATE downscale canvas if (typeof output === 'object') { newCanvas = output } else if (input.src || inputRemovable) { newCanvas = canvas } else { newCanvas = document.createElement('canvas') } newCanvas.width = dw newCanvas.height = dh newCtx = newCanvas.getContext('2d') } function getImageData(tmpBuffer) { if (!tmpBuffer) { return newCtx.getImageData(0, 0, dw, dh) } else { var imageData = newCtx.getImageData(0, 0, dw, dh) , byteBuffer = imageData.data , dindex for (dindex = 0; dindex < dwh4; dindex += 4) { byteBuffer[dindex] = tmpBuffer[dindex] * TIMES | 0 byteBuffer[dindex + 1] = tmpBuffer[dindex + 1] * TIMES | 0 byteBuffer[dindex + 2] = tmpBuffer[dindex + 2] * TIMES | 0 byteBuffer[dindex + 3] = HAS_ALPHA ? tmpBuffer[dindex + 3] * TIMES | 0 : 255 } // delete tmpBuffer return imageData } } if (scaleX > 1 || scaleY > 1) { // UPSCALE by bicubic function bicubic(t, a, b, c, d) { return 0.5 * (c - a + (2 * a - 5 * b + 4 * c - d + (3 * (b - c) + d - a) * t) * t) * t + b } setNewCanvas() imageData = getImageData() byteBuffer = imageData.data for (dy = 0; dy < dh; dy++) { sy = dy / scaleY isy = sy | 0 dsy = sy - isy row1 = isy * sw4 row0 = isy < 1 ? row1 : row1 - sw4 if (isy < sh - 2) { row2 = row1 + sw4 row3 = (isy + 2) * sw4 } else { row2 = row3 = isy > sh - 2 ? row1 : row1 + sw4 } for (dx = 0; dx < dw; dx++ , dindex += 4) { sx = dx / scaleX isx = sx | 0 dsx = sx - isx col1 = isx << 2 col0 = isx < 1 ? col1 : col1 - 4 if (isx < sw - 2) { col2 = col1 + 4 col3 = col1 + 8 } else { col2 = col3 = isx > sw - 2 ? col1 : col1 + 4 } // RED r = bicubic(dsy, bicubic(dsx , sourceBuffer[row0 + col0] , sourceBuffer[row0 + col1] , sourceBuffer[row0 + col2] , sourceBuffer[row0 + col3] ) , bicubic(dsx , sourceBuffer[row1 + col0] , sourceBuffer[row1 + col1] , sourceBuffer[row1 + col2] , sourceBuffer[row1 + col3] ) , bicubic(dsx , sourceBuffer[row2 + col0] , sourceBuffer[row2 + col1] , sourceBuffer[row2 + col2] , sourceBuffer[row2 + col3] ) , bicubic(dsx , sourceBuffer[row3 + col0] , sourceBuffer[row3 + col1] , sourceBuffer[row3 + col2] , sourceBuffer[row3 + col3] ) ) * TIMES | 0 // GREEN ++col0, ++col1, ++col2, ++col3 g = bicubic(dsy, bicubic(dsx , sourceBuffer[row0 + col0] , sourceBuffer[row0 + col1] , sourceBuffer[row0 + col2] , sourceBuffer[row0 + col3] ) , bicubic(dsx , sourceBuffer[row1 + col0] , sourceBuffer[row1 + col1] , sourceBuffer[row1 + col2] , sourceBuffer[row1 + col3] ) , bicubic(dsx , sourceBuffer[row2 + col0] , sourceBuffer[row2 + col1] , sourceBuffer[row2 + col2] , sourceBuffer[row2 + col3] ) , bicubic(dsx , sourceBuffer[row3 + col0] , sourceBuffer[row3 + col1] , sourceBuffer[row3 + col2] , sourceBuffer[row3 + col3] ) ) * TIMES | 0 // BLUE ++col0, ++col1, ++col2, ++col3 b = bicubic(dsy, bicubic(dsx , sourceBuffer[row0 + col0] , sourceBuffer[row0 + col1] , sourceBuffer[row0 + col2] , sourceBuffer[row0 + col3] ) , bicubic(dsx , sourceBuffer[row1 + col0] , sourceBuffer[row1 + col1] , sourceBuffer[row1 + col2] , sourceBuffer[row1 + col3] ) , bicubic(dsx , sourceBuffer[row2 + col0] , sourceBuffer[row2 + col1] , sourceBuffer[row2 + col2] , sourceBuffer[row2 + col3] ) , bicubic(dsx , sourceBuffer[row3 + col0] , sourceBuffer[row3 + col1] , sourceBuffer[row3 + col2] , sourceBuffer[row3 + col3] ) ) * TIMES | 0 byteBuffer[dindex] = r >= 0 ? r < 256 ? r : 255 : 0 byteBuffer[dindex + 1] = g >= 0 ? g < 256 ? g : 255 : 0 byteBuffer[dindex + 2] = b >= 0 ? b < 256 ? b : 255 : 0 if (HAS_ALPHA) { // ALPHA ++col0, ++col1, ++col2, ++col3 a = bicubic(dsy, bicubic(dsx , sourceBuffer[row0 + col0] , sourceBuffer[row0 + col1] , sourceBuffer[row0 + col2] , sourceBuffer[row0 + col3] ) , bicubic(dsx , sourceBuffer[row1 + col0] , sourceBuffer[row1 + col1] , sourceBuffer[row1 + col2] , sourceBuffer[row1 + col3] ) , bicubic(dsx , sourceBuffer[row2 + col0] , sourceBuffer[row2 + col1] , sourceBuffer[row2 + col2] , sourceBuffer[row2 + col3] ) , bicubic(dsx , sourceBuffer[row3 + col0] , sourceBuffer[row3 + col1] , sourceBuffer[row3 + col2] , sourceBuffer[row3 + col3] ) ) * TIMES | 0 byteBuffer[dindex + 3] = a >= 0 ? a < 256 ? a : 255 : 0 } else { byteBuffer[dindex + 3] = 255 } } } } else { // DOWNSCALE if (root.Float32Array) { tmpBuffer = new Float32Array(dwh4) } else { tmpBuffer = [] for (dindex = 0; dindex < dwh4; ++dindex) { tmpBuffer[dindex] = 0 } } // CREATE float buffer for (sy = 0; sy < sh; sy++) { dy = sy * scaleY idy = dy | 0 dyindex = idy * dw4 crossY = (!!((idy - (dy + scaleY | 0)) * (sh - 1 - sy))) << 1 if (crossY) { wy = idy + 1 - dy nwy = dy + scaleY - idy - 1 } for (sx = 0; sx < sw; sx++ , sindex += 4) { dx = sx * scaleX idx = dx | 0 dindex = dyindex + (idx << 2) crossX = !!((idx - (dx + scaleX | 0)) * (sw - 1 - sx)) if (crossX) { wx = idx + 1 - dx nwx = dx + scaleX - idx - 1 } r = sourceBuffer[sindex] g = sourceBuffer[sindex + 1] b = sourceBuffer[sindex + 2] if (HAS_ALPHA) a = sourceBuffer[sindex + 3] switch (crossX + crossY) { case 0: tmpBuffer[dindex] += r * scaleXY tmpBuffer[dindex + 1] += g * scaleXY tmpBuffer[dindex + 2] += b * scaleXY if (HAS_ALPHA) tmpBuffer[dindex + 3] += a * scaleXY break case 1: w = wx * scaleY tmpBuffer[dindex] += r * w tmpBuffer[dindex + 1] += g * w tmpBuffer[dindex + 2] += b * w if (HAS_ALPHA) tmpBuffer[dindex + 3] += a * w w = nwx * scaleY tmpBuffer[dindex + 4] += r * w tmpBuffer[dindex + 5] += g * w tmpBuffer[dindex + 6] += b * w if (HAS_ALPHA) tmpBuffer[dindex + 7] += a * w break case 2: w = scaleX * wy tmpBuffer[dindex] += r * w tmpBuffer[dindex + 1] += g * w tmpBuffer[dindex + 2] += b * w if (HAS_ALPHA) tmpBuffer[dindex + 3] += a * w w = scaleX * nwy dindex += dw4 tmpBuffer[dindex] += r * w tmpBuffer[dindex + 1] += g * w tmpBuffer[dindex + 2] += b * w if (HAS_ALPHA) tmpBuffer[dindex + 3] += a * w break default: w = wx * wy tmpBuffer[dindex] += r * w tmpBuffer[dindex + 1] += g * w tmpBuffer[dindex + 2] += b * w if (HAS_ALPHA) tmpBuffer[dindex + 3] += a * w w = nwx * wy tmpBuffer[dindex + 4] += r * w tmpBuffer[dindex + 5] += g * w tmpBuffer[dindex + 6] += b * w if (HAS_ALPHA) tmpBuffer[dindex + 7] += a * w w = wx * nwy dindex += dw4 tmpBuffer[dindex] += r * w tmpBuffer[dindex + 1] += g * w tmpBuffer[dindex + 2] += b * w if (HAS_ALPHA) tmpBuffer[dindex + 3] += a * w w = nwx * nwy tmpBuffer[dindex + 4] += r * w tmpBuffer[dindex + 5] += g * w tmpBuffer[dindex + 6] += b * w if (HAS_ALPHA) tmpBuffer[dindex + 7] += a * w break } } } // delete sourceBuffer setNewCanvas() imageData = getImageData(tmpBuffer) } newCtx.putImageData(imageData, 0, 0) if (typeof output === 'string') { if (output === 'png' || output === 'jpeg') { var img if (inputRemovable && input.src) { img = input } else { img = new Image() } img.width = dw img.height = dh img.src = newCanvas.toDataURL('image/' + output, 1) return img } else if (output === 'png-src' || output === 'jpeg-src') { return newCanvas.toDataURL('image/' + output.split('-')[0], 1) } } return newCanvas } module.exports = scale;