{"version":3,"sources":["../src/index.js"],"names":["throwError","isNodePattern","rotate90degrees","bitmap","dstBuffer","clockwise","dstOffsetStep","dstOffset","length","tmp","x","y","srcOffset","width","height","data","readUInt32BE","writeUInt32BE","advancedRotate","deg","mode","rad","Math","PI","cosine","cos","sine","sin","w","h","ceil","abs","c","cloneQuiet","scanQuiet","idx","_background","max","resize","blit","bW","bH","Buffer","alloc","createTranslationFunction","deltaX","deltaY","translate2Cartesian","translate2Screen","cartesian","source","dstIdx","srcIdx","pixelRGBA","crop","rotate","cb","call"],"mappings":"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","sourcesContent":["import { throwError, isNodePattern } from '@jimp/utils';\n\nfunction rotate90degrees(bitmap, dstBuffer, clockwise) {\n const dstOffsetStep = clockwise ? -4 : 4;\n let dstOffset = clockwise ? dstBuffer.length - 4 : 0;\n\n let tmp;\n let x;\n let y;\n let srcOffset;\n\n for (x = 0; x < bitmap.width; x++) {\n for (y = bitmap.height - 1; y >= 0; y--) {\n srcOffset = (bitmap.width * y + x) << 2;\n tmp = bitmap.data.readUInt32BE(srcOffset, true);\n dstBuffer.writeUInt32BE(tmp, dstOffset, true);\n dstOffset += dstOffsetStep;\n }\n }\n}\n\n/**\n * Rotates an image clockwise by an arbitrary number of degrees. NB: 'this' must be a Jimp object.\n * @param {number} deg the number of degrees to rotate the image by\n * @param {string|boolean} mode (optional) resize mode or a boolean, if false then the width and height of the image will not be changed\n */\nfunction advancedRotate(deg, mode) {\n deg %= 360;\n const rad = (deg * Math.PI) / 180;\n const cosine = Math.cos(rad);\n const sine = Math.sin(rad);\n\n // the final width and height will change if resize == true\n let w = this.bitmap.width;\n let h = this.bitmap.height;\n\n if (mode === true || typeof mode === 'string') {\n // resize the image to it maximum dimension and blit the existing image\n // onto the center so that when it is rotated the image is kept in bounds\n\n // http://stackoverflow.com/questions/3231176/how-to-get-size-of-a-rotated-rectangle\n // Plus 1 border pixel to ensure to show all rotated result for some cases.\n w =\n Math.ceil(\n Math.abs(this.bitmap.width * cosine) +\n Math.abs(this.bitmap.height * sine)\n ) + 1;\n h =\n Math.ceil(\n Math.abs(this.bitmap.width * sine) +\n Math.abs(this.bitmap.height * cosine)\n ) + 1;\n // Ensure destination to have even size to a better result.\n if (w % 2 !== 0) {\n w++;\n }\n\n if (h % 2 !== 0) {\n h++;\n }\n\n const c = this.cloneQuiet();\n this.scanQuiet(0, 0, this.bitmap.width, this.bitmap.height, function(\n x,\n y,\n idx\n ) {\n this.bitmap.data.writeUInt32BE(this._background, idx);\n });\n\n const max = Math.max(w, h, this.bitmap.width, this.bitmap.height);\n this.resize(max, max, mode);\n\n this.blit(\n c,\n this.bitmap.width / 2 - c.bitmap.width / 2,\n this.bitmap.height / 2 - c.bitmap.height / 2\n );\n }\n\n const bW = this.bitmap.width;\n const bH = this.bitmap.height;\n const dstBuffer = Buffer.alloc(this.bitmap.data.length);\n\n function createTranslationFunction(deltaX, deltaY) {\n return function(x, y) {\n return {\n x: x + deltaX,\n y: y + deltaY\n };\n };\n }\n\n const translate2Cartesian = createTranslationFunction(-(bW / 2), -(bH / 2));\n const translate2Screen = createTranslationFunction(\n bW / 2 + 0.5,\n bH / 2 + 0.5\n );\n\n for (let y = 1; y <= bH; y++) {\n for (let x = 1; x <= bW; x++) {\n const cartesian = translate2Cartesian(x, y);\n const source = translate2Screen(\n cosine * cartesian.x - sine * cartesian.y,\n cosine * cartesian.y + sine * cartesian.x\n );\n const dstIdx = (bW * (y - 1) + x - 1) << 2;\n\n if (source.x >= 0 && source.x < bW && source.y >= 0 && source.y < bH) {\n const srcIdx = ((bW * (source.y | 0) + source.x) | 0) << 2;\n const pixelRGBA = this.bitmap.data.readUInt32BE(srcIdx);\n dstBuffer.writeUInt32BE(pixelRGBA, dstIdx);\n } else {\n // reset off-image pixels\n dstBuffer.writeUInt32BE(this._background, dstIdx);\n }\n }\n }\n this.bitmap.data = dstBuffer;\n\n if (mode === true || typeof mode === 'string') {\n // now crop the image to the final size\n const x = bW / 2 - w / 2;\n const y = bH / 2 - h / 2;\n this.crop(x, y, w, h);\n }\n}\n\nexport default () => ({\n /**\n * Rotates the image clockwise by a number of degrees. By default the width and height of the image will be resized appropriately.\n * @param {number} deg the number of degrees to rotate the image by\n * @param {string|boolean} mode (optional) resize mode or a boolean, if false then the width and height of the image will not be changed\n * @param {function(Error, Jimp)} cb (optional) a callback for when complete\n * @returns {Jimp} this for chaining of methods\n */\n rotate(deg, mode, cb) {\n // enable overloading\n if (typeof mode === 'undefined' || mode === null) {\n // e.g. image.resize(120);\n // e.g. image.resize(120, null, cb);\n // e.g. image.resize(120, undefined, cb);\n mode = true;\n }\n\n if (typeof mode === 'function' && typeof cb === 'undefined') {\n // e.g. image.resize(120, cb);\n cb = mode;\n mode = true;\n }\n\n if (typeof deg !== 'number') {\n return throwError.call(this, 'deg must be a number', cb);\n }\n\n if (typeof mode !== 'boolean' && typeof mode !== 'string') {\n return throwError.call(this, 'mode must be a boolean or a string', cb);\n }\n\n advancedRotate.call(this, deg, mode, cb);\n\n if (isNodePattern(cb)) {\n cb.call(this, null, this);\n }\n\n return this;\n }\n});\n"],"file":"index.js"}