{"version":3,"file":"index.js","names":["isNodePattern","throwError","matrixRotate","deg","Math","abs","Error","w","bitmap","width","h","height","angle","nW","nH","dstBuffer","Buffer","alloc","data","length","createIdxTranslationFunction","x","y","srcIdxFunction","dstIdxFunction","srcIdx","pixelRGBA","readUInt32BE","dstIdx","writeUInt32BE","advancedRotate","mode","rad","PI","cosine","cos","sine","sin","ceil","c","cloneQuiet","scanQuiet","idx","_background","max","resize","blit","bW","bH","createTranslationFunction","deltaX","deltaY","translate2Cartesian","translate2Screen","cartesian","source","crop","rotate","cb","call","matrixRotateAllowed"],"sources":["../src/index.js"],"sourcesContent":["import { isNodePattern, throwError } from \"@jimp/utils\";\n\n/**\n * Rotates an image counter-clockwise by multiple of 90 degrees. NB: 'this' must be a Jimp object.\n *\n * This function is based on matrix rotation. Check this to get an initial idea how it works: https://stackoverflow.com/a/8664879/10561909\n *\n * @param {number} deg the number of degrees to rotate the image by, it should be a multiple of 90\n */\nfunction matrixRotate(deg) {\n if (Math.abs(deg) % 90 !== 0) {\n throw new Error(\"Unsupported matrix rotation degree\");\n }\n\n deg %= 360;\n if (Math.abs(deg) === 0) {\n // no rotation for 0, 360, -360, 720, -720, ...\n return;\n }\n\n const w = this.bitmap.width;\n const h = this.bitmap.height;\n\n // decide which rotation angle to use\n let angle;\n switch (deg) {\n // 90 degree & -270 degree are same\n case 90:\n case -270:\n angle = 90;\n break;\n\n case 180:\n case -180:\n angle = 180;\n break;\n\n case 270:\n case -90:\n angle = -90;\n break;\n\n default:\n throw new Error(\"Unsupported matrix rotation degree\");\n }\n // After this switch block, angle will be 90, 180 or -90\n\n // calculate the new width and height\n const nW = angle === 180 ? w : h;\n const nH = angle === 180 ? h : w;\n\n const dstBuffer = Buffer.alloc(this.bitmap.data.length);\n\n // function to translate the x, y coordinate to the index of the pixel in the buffer\n function createIdxTranslationFunction(w, h) {\n return function (x, y) {\n return (y * w + x) << 2;\n };\n }\n\n const srcIdxFunction = createIdxTranslationFunction(w, h);\n const dstIdxFunction = createIdxTranslationFunction(nW, nH);\n\n for (let x = 0; x < w; x++) {\n for (let y = 0; y < h; y++) {\n const srcIdx = srcIdxFunction(x, y);\n const pixelRGBA = this.bitmap.data.readUInt32BE(srcIdx);\n\n let dstIdx;\n switch (angle) {\n case 90:\n dstIdx = dstIdxFunction(y, w - x - 1);\n break;\n case -90:\n dstIdx = dstIdxFunction(h - y - 1, x);\n break;\n case 180:\n dstIdx = dstIdxFunction(w - x - 1, h - y - 1);\n break;\n default:\n throw new Error(\"Unsupported matrix rotation angle\");\n }\n\n dstBuffer.writeUInt32BE(pixelRGBA, dstIdx);\n }\n }\n\n this.bitmap.data = dstBuffer;\n this.bitmap.width = nW;\n this.bitmap.height = nH;\n}\n\n/**\n * Rotates an image counter-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(\n 0,\n 0,\n this.bitmap.width,\n this.bitmap.height,\n function (x, y, idx) {\n this.bitmap.data.writeUInt32BE(this._background, idx);\n }\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\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 counter-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 // use matrixRotate if the angle is a multiple of 90 degrees (eg: 180 or -90) and resize is allowed or not needed.\n const matrixRotateAllowed =\n deg % 90 === 0 &&\n (mode || this.bitmap.width === this.bitmap.height || deg % 180 === 0);\n\n if (matrixRotateAllowed) {\n matrixRotate.call(this, deg);\n } else {\n advancedRotate.call(this, deg, mode, cb);\n }\n\n if (isNodePattern(cb)) {\n cb.call(this, null, this);\n }\n\n return this;\n },\n});\n"],"mappings":"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"}