pica 10.0.1 → 10.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"pica.min.mjs","names":[],"sources":["../../multimath/lib/base64decode.mjs","../../multimath/lib/wa_detect.mjs","../../multimath/lib/multimath.mjs","../node_modules/glur/lib/blur_mono16.mjs","../src/mm_unsharp_mask/unsharp_mask.ts","../src/mm_unsharp_mask/unsharp_mask_wasm.ts","../src/mm_unsharp_mask/unsharp_mask_wasm_base64.ts","../src/mm_unsharp_mask/index.ts","../src/mm_resize/resize_filter_info.ts","../src/mm_resize/resize_filter_gen.ts","../src/mm_resize/convolve.ts","../src/mm_resize/resize.ts","../src/mm_resize/resize_wasm.ts","../src/mm_resize/convolve_wasm_base64.ts","../src/mm_resize/index.ts","../src/mathlib.ts","../src/pool.ts","../src/utils.ts","../src/stepper.ts","../src/tiler.ts","../src/supported_features.ts","../src/pica_main.ts"],"sourcesContent":["// base64 decode str -> Uint8Array, to load WA modules\n//\nconst BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n\nexport default function base64decode (str) {\n const input = str.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length\n\n const out = new Uint8Array((max * 3) >> 2)\n\n // Collect by 6*4 bits (3 bytes)\n\n let bits = 0\n let ptr = 0\n\n for (let idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n out[ptr++] = (bits >> 16) & 0xFF\n out[ptr++] = (bits >> 8) & 0xFF\n out[ptr++] = bits & 0xFF\n }\n\n bits = (bits << 6) | BASE64_MAP.indexOf(input.charAt(idx))\n }\n\n // Dump tail\n\n const tailbits = (max % 4) * 6\n\n if (tailbits === 0) {\n out[ptr++] = (bits >> 16) & 0xFF\n out[ptr++] = (bits >> 8) & 0xFF\n out[ptr++] = bits & 0xFF\n } else if (tailbits === 18) {\n out[ptr++] = (bits >> 10) & 0xFF\n out[ptr++] = (bits >> 2) & 0xFF\n } else if (tailbits === 12) {\n out[ptr++] = (bits >> 4) & 0xFF\n }\n\n return out\n}\n","// Detect WebAssembly support.\n// - Check global WebAssembly object\n// - Try to load simple module (can be disabled via CSP)\n//\nlet wa\n\nexport default function hasWebAssembly () {\n // use cache if called before;\n if (typeof wa !== 'undefined') return wa\n\n wa = false\n\n if (typeof WebAssembly === 'undefined') return wa\n\n // If WebAssenbly is disabled, code can throw on compile\n try {\n // https://github.com/brion/min-wasm-fail/blob/master/min-wasm-fail.in.js\n // Additional check that WA internals are correct\n\n const bin = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 6, 1, 96, 1, 127, 1, 127, 3, 2, 1, 0, 5, 3, 1, 0, 1, 7, 8, 1, 4, 116, 101, 115, 116, 0, 0, 10, 16, 1, 14, 0, 32, 0, 65, 1, 54, 2, 0, 32, 0, 40, 2, 0, 11])\n const module = new WebAssembly.Module(bin)\n const instance = new WebAssembly.Instance(module, {})\n\n // test storing to and loading from a non-zero location via a parameter.\n // Safari on iOS 11.2.5 returns 0 unexpectedly at non-zero locations\n if (instance.exports.test(4) !== 0) wa = true\n\n return wa\n } catch (__) {}\n\n return wa\n}\n","import base64decode from './base64decode.mjs'\nimport hasWebAssembly from './wa_detect.mjs'\n\nconst DEFAULT_OPTIONS = {\n js: true,\n wasm: true\n}\n\nclass MultiMath {\n constructor (options) {\n const opts = Object.assign({}, DEFAULT_OPTIONS, options || {})\n\n this.options = opts\n\n this.__cache = {}\n\n this.__init_promise = null\n this.__modules = opts.modules || {}\n this.__memory = null\n this.__wasm = {}\n\n this.__isLE = ((new Uint32Array((new Uint8Array([1, 0, 0, 0])).buffer))[0] === 1)\n\n if (!this.options.js && !this.options.wasm) {\n throw new Error('mathlib: at least \"js\" or \"wasm\" should be enabled')\n }\n }\n\n has_wasm () { return hasWebAssembly() }\n\n use (module) {\n this.__modules[module.name] = module\n\n // Pin the best possible implementation\n if (this.options.wasm && this.has_wasm() && module.wasm_fn) {\n this[module.name] = module.wasm_fn\n } else {\n this[module.name] = module.fn\n }\n\n return this\n }\n\n init () {\n if (this.__init_promise) return this.__init_promise\n\n if (!this.options.js && this.options.wasm && !this.has_wasm()) {\n return Promise.reject(new Error('mathlib: only \"wasm\" was enabled, but it\\'s not supported'))\n }\n\n this.__init_promise = Promise.all(Object.keys(this.__modules).map(name => {\n const module = this.__modules[name]\n\n if (!this.options.wasm || !this.has_wasm() || !module.wasm_fn) return null\n\n // If already compiled - exit\n if (this.__wasm[name]) return null\n\n // Compile wasm source\n return WebAssembly.compile(base64decode(module.wasm_src))\n .then(m => { this.__wasm[name] = m })\n }))\n .then(() => this)\n\n return this.__init_promise\n }\n\n // //////////////////////////////////////////////////////////////////////////////\n // Methods below are for internal use from plugins\n\n // Increase current memory to include specified number of bytes. Do nothing if\n // size is already ok. You probably don't need to call this method directly,\n // because it will be invoked from `.__instance()`.\n //\n __reallocate (bytes) {\n if (!this.__memory) {\n this.__memory = new WebAssembly.Memory({\n initial: Math.ceil(bytes / (64 * 1024))\n })\n return this.__memory\n }\n\n const mem_size = this.__memory.buffer.byteLength\n\n if (mem_size < bytes) {\n this.__memory.grow(Math.ceil((bytes - mem_size) / (64 * 1024)))\n }\n\n return this.__memory\n }\n\n // Returns instantinated webassembly item by name, with specified memory size\n // and environment.\n // - use cache if available\n // - do sync module init, if async init was not called earlier\n // - allocate memory if not enougth\n // - can export functions to webassembly via \"env_extra\",\n // for example, { exp: Math.exp }\n //\n __instance (name, memsize, env_extra) {\n if (memsize) this.__reallocate(memsize)\n\n // If .init() was not called, do sync compile\n if (!this.__wasm[name]) {\n const module = this.__modules[name]\n this.__wasm[name] = new WebAssembly.Module(base64decode(module.wasm_src))\n }\n\n if (!this.__cache[name]) {\n const env_base = {\n memoryBase: 0,\n memory: this.__memory,\n tableBase: 0,\n table: new WebAssembly.Table({ initial: 0, element: 'anyfunc' })\n }\n\n this.__cache[name] = new WebAssembly.Instance(this.__wasm[name], {\n env: Object.assign(env_base, env_extra || {})\n })\n }\n\n return this.__cache[name]\n }\n\n // Helper to calculate memory aligh for pointers. Webassembly does not require\n // this, but you may wish to experiment. Default base = 8;\n //\n __align (number, base) {\n base = base || 8\n const reminder = number % base\n return number + (reminder ? base - reminder : 0)\n }\n}\n\nexport default MultiMath\n","// Calculate Gaussian blur of an image using IIR filter\n// The method is taken from Intel's white paper and code example attached to it:\n// https://software.intel.com/en-us/articles/iir-gaussian-blur-filter\n// -implementation-using-intel-advanced-vector-extensions\n\nfunction gaussCoef (sigma) {\n if (sigma < 0.5) {\n sigma = 0.5\n }\n\n const a = Math.exp(0.726 * 0.726) / sigma,\n g1 = Math.exp(-a),\n g2 = Math.exp(-2 * a),\n k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2)\n\n const a0 = k\n const a1 = k * (a - 1) * g1\n const a2 = k * (a + 1) * g1\n const a3 = -k * g2\n const b1 = 2 * g1\n const b2 = -g2\n const left_corner = (a0 + a1) / (1 - b1 - b2)\n const right_corner = (a2 + a3) / (1 - b1 - b2)\n\n // Attempt to force type to FP32.\n return new Float32Array([a0, a1, a2, a3, b1, b2, left_corner, right_corner])\n}\n\nfunction convolveMono16 (src, out, line, coeff, width, height) {\n // takes src image and writes the blurred and transposed result into out\n\n let prev_src, curr_src, curr_out, prev_out, prev_prev_out\n let src_index, out_index, line_index\n let i, j\n let coeff_a0, coeff_a1, coeff_b1, coeff_b2\n\n for (i = 0; i < height; i++) {\n src_index = i * width\n out_index = i\n line_index = 0\n\n // left to right\n prev_src = src[src_index]\n prev_prev_out = prev_src * coeff[6]\n prev_out = prev_prev_out\n\n coeff_a0 = coeff[0]\n coeff_a1 = coeff[1]\n coeff_b1 = coeff[4]\n coeff_b2 = coeff[5]\n\n for (j = 0; j < width; j++) {\n curr_src = src[src_index]\n\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2\n\n prev_prev_out = prev_out\n prev_out = curr_out\n prev_src = curr_src\n\n line[line_index] = prev_out\n line_index++\n src_index++\n }\n\n src_index--\n line_index--\n out_index += height * (width - 1)\n\n // right to left\n prev_src = src[src_index]\n prev_prev_out = prev_src * coeff[7]\n prev_out = prev_prev_out\n curr_src = prev_src\n\n coeff_a0 = coeff[2]\n coeff_a1 = coeff[3]\n\n for (j = width - 1; j >= 0; j--) {\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2\n\n prev_prev_out = prev_out\n prev_out = curr_out\n\n prev_src = curr_src\n curr_src = src[src_index]\n\n out[out_index] = line[line_index] + prev_out\n\n src_index--\n line_index--\n out_index -= height\n }\n }\n}\n\nfunction blurMono16 (src, width, height, radius) {\n // Quick exit on zero radius\n if (!radius) { return }\n\n const out = new Uint16Array(src.length),\n tmp_line = new Float32Array(Math.max(width, height))\n\n const coeff = gaussCoef(radius)\n\n convolveMono16(src, out, tmp_line, coeff, width, height, radius)\n convolveMono16(out, src, tmp_line, coeff, height, width, radius)\n}\n\nexport default blurMono16\n","// Unsharp mask filter\n//\n// http://stackoverflow.com/a/23322820/1031804\n// USM(O) = O + (2 * (Amount / 100) * (O - GB))\n// GB - gaussian blur.\n//\n// Image is converted from RGB to HSV, unsharp mask is applied to the\n// brightness channel and then image is converted back to RGB.\n//\nimport { blurMono16 } from 'glur'\nimport type { MathImageBuffer } from '../mathlib'\n\nfunction hsv_v16 (img: MathImageBuffer, width: number, height: number): Uint16Array {\n const size = width * height\n const out = new Uint16Array(size)\n let r, g, b, max\n for (let i = 0; i < size; i++) {\n r = img[4 * i]\n g = img[4 * i + 1]\n b = img[4 * i + 2]\n max = (r >= g && r >= b) ? r : (g >= b && g >= r) ? g : b\n out[i] = max << 8\n }\n return out\n}\n\nexport default function unsharp (\n img: MathImageBuffer,\n width: number,\n height: number,\n amount: number,\n radius: number,\n threshold: number\n): void {\n let v1, v2, vmul\n let diff, iTimes4\n\n if (amount === 0 || radius < 0.5) {\n return\n }\n if (radius > 2.0) {\n radius = 2.0\n }\n\n const brightness = hsv_v16(img, width, height)\n\n const blured = new Uint16Array(brightness) // copy, because blur modifies src\n\n blurMono16(blured, width, height, radius)\n\n const amountFp = (amount / 100 * 0x1000 + 0.5)|0\n const thresholdFp = threshold << 8\n\n const size = width * height\n\n for (let i = 0; i < size; i++) {\n v1 = brightness[i]\n diff = v1 - blured[i]\n\n if (Math.abs(diff) >= thresholdFp) {\n // add unsharp mask to the brightness channel\n v2 = v1 + ((amountFp * diff + 0x800) >> 12)\n\n // Both v1 and v2 are within [0.0 .. 255.0] (0000-FF00) range, never going into\n // [255.003 .. 255.996] (FF01-FFFF). This allows to round this value as (x+.5)|0\n // later without overflowing.\n v2 = v2 > 0xff00 ? 0xff00 : v2\n v2 = v2 < 0x0000 ? 0x0000 : v2\n\n // Avoid division by 0. V=0 means rgb(0,0,0), unsharp with unsharpAmount>0 cannot\n // change this value (because diff between colors gets inflated), so no need to verify correctness.\n v1 = v1 !== 0 ? v1 : 1\n\n // Multiplying V in HSV model by a constant is equivalent to multiplying each component\n // in RGB by the same constant (same for HSL), see also:\n // https://beesbuzz.biz/code/16-hsv-color-transforms\n vmul = ((v2 << 12) / v1)|0\n\n // Result will be in [0..255] range because:\n // - all numbers are positive\n // - r,g,b <= (v1/256)\n // - r,g,b,(v1/256),(v2/256) <= 255\n // So highest this number can get is X*255/X+0.5=255.5 which is < 256 and rounds down.\n\n iTimes4 = i * 4\n img[iTimes4] = (img[iTimes4] * vmul + 0x800) >> 12 // R\n img[iTimes4 + 1] = (img[iTimes4 + 1] * vmul + 0x800) >> 12 // G\n img[iTimes4 + 2] = (img[iTimes4 + 2] * vmul + 0x800) >> 12 // B\n }\n }\n}\n","import type { MathWasmContext, MathImageBuffer } from '../mathlib'\n\nexport default function unsharp (\n this: MathWasmContext,\n img: MathImageBuffer,\n width: number,\n height: number,\n amount: number,\n radius: number,\n threshold: number\n): void {\n if (amount === 0 || radius < 0.5) {\n return\n }\n\n if (radius > 2.0) {\n radius = 2.0\n }\n\n const pixels = width * height\n\n const img_bytes_cnt = pixels * 4\n const hsv_bytes_cnt = pixels * 2\n const blur_bytes_cnt = pixels * 2\n const blur_line_byte_cnt = Math.max(width, height) * 4 // float32 array\n const blur_coeffs_byte_cnt = 8 * 4 // float32 array\n\n const img_offset = 0\n const hsv_offset = img_bytes_cnt\n const blur_offset = hsv_offset + hsv_bytes_cnt\n const blur_tmp_offset = blur_offset + blur_bytes_cnt\n const blur_line_offset = blur_tmp_offset + blur_bytes_cnt\n const blur_coeffs_offset = blur_line_offset + blur_line_byte_cnt\n\n const instance = this.__instance(\n 'unsharp_mask',\n img_bytes_cnt + hsv_bytes_cnt + blur_bytes_cnt * 2 + blur_line_byte_cnt + blur_coeffs_byte_cnt,\n { exp: Math.exp }\n )\n\n // 32-bit copy is much faster in chrome\n const img32 = new Uint32Array(img.buffer)\n const mem32 = new Uint32Array(this.__memory!.buffer)\n mem32.set(img32)\n\n // HSL\n let fn = (instance.exports.hsv_v16 || instance.exports._hsv_v16) as Function | undefined\n if (!fn) throw new Error('WASM hsv_v16 function is not available')\n fn(img_offset, hsv_offset, width, height)\n\n // BLUR\n fn = (instance.exports.blurMono16 || instance.exports._blurMono16) as Function | undefined\n if (!fn) throw new Error('WASM blurMono16 function is not available')\n fn(hsv_offset, blur_offset, blur_tmp_offset,\n blur_line_offset, blur_coeffs_offset, width, height, radius)\n\n // UNSHARP\n fn = (instance.exports.unsharp || instance.exports._unsharp) as Function | undefined\n if (!fn) throw new Error('WASM unsharp function is not available')\n fn(img_offset, img_offset, hsv_offset,\n blur_offset, width, height, amount, threshold)\n\n // 32-bit copy is much faster in chrome\n img32.set(new Uint32Array(this.__memory!.buffer, 0, pixels))\n}\n","// This is autogenerated file from math.wasm, don't edit.\n//\nexport default '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'\n","import fn from './unsharp_mask'\nimport wasm_fn from './unsharp_mask_wasm'\nimport wasm_src from './unsharp_mask_wasm_base64'\n\nexport default {\n name: 'unsharp_mask' as const,\n fn,\n wasm_fn,\n wasm_src\n}\n","import type { MathResizeFilter } from '../mathlib'\n\n// Filter definitions to build tables for\n// resizing convolvers.\n//\n// Presets for quality 0..3. Filter functions + window size\n//\nexport interface FilterInfo {\n win: number\n fn: (x: number) => number\n}\n\nconst filter: Record<MathResizeFilter, FilterInfo> = {\n // Nearest neighbor\n box: {\n win: 0.5,\n fn (x: number) {\n if (x < 0) x = -x\n return (x < 0.5) ? 1.0 : 0.0\n }\n },\n // // Hamming\n hamming: {\n win: 1.0,\n fn (x: number) {\n if (x < 0) x = -x\n if (x >= 1.0) { return 0.0 }\n if (x < 1.19209290E-07) { return 1.0 }\n const xpi = x * Math.PI\n return ((Math.sin(xpi) / xpi) * (0.54 + 0.46 * Math.cos(xpi / 1.0)))\n }\n },\n // Lanczos, win = 2\n lanczos2: {\n win: 2.0,\n fn (x: number) {\n if (x < 0) x = -x\n if (x >= 2.0) { return 0.0 }\n if (x < 1.19209290E-07) { return 1.0 }\n const xpi = x * Math.PI\n return (Math.sin(xpi) / xpi) * Math.sin(xpi / 2.0) / (xpi / 2.0)\n }\n },\n // Lanczos, win = 3\n lanczos3: {\n win: 3.0,\n fn (x: number) {\n if (x < 0) x = -x\n if (x >= 3.0) { return 0.0 }\n if (x < 1.19209290E-07) { return 1.0 }\n const xpi = x * Math.PI\n return (Math.sin(xpi) / xpi) * Math.sin(xpi / 3.0) / (xpi / 3.0)\n }\n },\n // Magic Kernel Sharp 2013, win = 2.5\n // http://johncostella.com/magic/\n mks2013: {\n win: 2.5,\n fn (x: number) {\n if (x < 0) x = -x\n if (x >= 2.5) { return 0.0 }\n if (x >= 1.5) { return -0.125 * (x - 2.5) * (x - 2.5) }\n if (x >= 0.5) { return 0.25 * (4 * x * x - 11 * x + 7) }\n return 1.0625 - 1.75 * x * x\n }\n }\n}\n\nexport default {\n filter\n}\n","// Calculate convolution filters for each destination point,\n// and pack data to Int16Array:\n//\n// [ shift, length, data..., shift2, length2, data..., ... ]\n//\n// - shift - offset in src image\n// - length - filter length (in src points)\n// - data - filter values sequence\n//\nimport FILTER_INFO from './resize_filter_info'\nimport type { MathResizeFilter } from '../mathlib'\n\n// Precision of fixed FP values\nconst FIXED_FRAC_BITS = 14\n\nfunction toFixedPoint (num: number): number {\n return Math.round(num * ((1 << FIXED_FRAC_BITS) - 1))\n}\n\nexport default function resizeFilterGen (\n filter: MathResizeFilter,\n srcSize: number,\n destSize: number,\n scale: number,\n offset: number\n): Int16Array {\n const filterFunction = FILTER_INFO.filter[filter].fn\n\n const scaleInverted = 1.0 / scale\n const scaleClamped = Math.min(1.0, scale) // For upscale\n\n // Filter window (averaging interval), scaled to src image\n const srcWindow = FILTER_INFO.filter[filter].win / scaleClamped\n\n let destPixel, srcPixel, srcFirst, srcLast, filterElementSize,\n floatFilter, fxpFilter, total, pxl, idx, floatVal, filterTotal, filterVal\n let leftNotEmpty, rightNotEmpty, filterShift, filterSize\n\n const maxFilterElementSize = Math.floor((srcWindow + 1) * 2)\n const packedFilter = new Int16Array((maxFilterElementSize + 2) * destSize)\n let packedFilterPtr = 0\n\n const slowCopy = !packedFilter.subarray || !packedFilter.set\n\n // For each destination pixel calculate source range and built filter values\n for (destPixel = 0; destPixel < destSize; destPixel++) {\n // Scaling should be done relative to central pixel point\n srcPixel = (destPixel + 0.5) * scaleInverted + offset\n\n srcFirst = Math.max(0, Math.floor(srcPixel - srcWindow))\n srcLast = Math.min(srcSize - 1, Math.ceil(srcPixel + srcWindow))\n\n filterElementSize = srcLast - srcFirst + 1\n floatFilter = new Float32Array(filterElementSize)\n fxpFilter = new Int16Array(filterElementSize)\n\n total = 0.0\n\n // Fill filter values for calculated range\n for (pxl = srcFirst, idx = 0; pxl <= srcLast; pxl++, idx++) {\n floatVal = filterFunction(((pxl + 0.5) - srcPixel) * scaleClamped)\n total += floatVal\n floatFilter[idx] = floatVal\n }\n\n // Normalize filter, convert to fixed point and accumulate conversion error\n filterTotal = 0\n\n for (idx = 0; idx < floatFilter.length; idx++) {\n filterVal = floatFilter[idx] / total\n filterTotal += filterVal\n fxpFilter[idx] = toFixedPoint(filterVal)\n }\n\n // Compensate normalization error, to minimize brightness drift\n fxpFilter[destSize >> 1] += toFixedPoint(1.0 - filterTotal)\n\n //\n // Now pack filter to useable form\n //\n // 1. Trim leading and trailing zero values, and compensate shift/length\n // 2. Put all to single array in this format:\n //\n // [ pos shift, data length, value1, value2, value3, ... ]\n //\n\n leftNotEmpty = 0\n while (leftNotEmpty < fxpFilter.length && fxpFilter[leftNotEmpty] === 0) {\n leftNotEmpty++\n }\n\n if (leftNotEmpty < fxpFilter.length) {\n rightNotEmpty = fxpFilter.length - 1\n while (rightNotEmpty > 0 && fxpFilter[rightNotEmpty] === 0) {\n rightNotEmpty--\n }\n\n filterShift = srcFirst + leftNotEmpty\n filterSize = rightNotEmpty - leftNotEmpty + 1\n\n packedFilter[packedFilterPtr++] = filterShift // shift\n packedFilter[packedFilterPtr++] = filterSize // size\n\n if (!slowCopy) {\n packedFilter.set(fxpFilter.subarray(leftNotEmpty, rightNotEmpty + 1), packedFilterPtr)\n packedFilterPtr += filterSize\n } else {\n // fallback for old IE < 11, without subarray/set methods\n for (idx = leftNotEmpty; idx <= rightNotEmpty; idx++) {\n packedFilter[packedFilterPtr++] = fxpFilter[idx]\n }\n }\n } else {\n // zero data, write header only\n packedFilter[packedFilterPtr++] = 0 // shift\n packedFilter[packedFilterPtr++] = 0 // size\n }\n }\n return packedFilter\n}\n","// Resize convolvers, pure JS implementation\n//\n// Precision of fixed FP values\n// var FIXED_FRAC_BITS = 14;\n\nfunction clampTo8 (i: number): number { return i < 0 ? 0 : (i > 255 ? 255 : i) }\nfunction clampNegative (i: number): number { return i >= 0 ? i : 0 }\n\nimport type { MathImageBuffer } from '../mathlib'\n\n// Convolve image data in horizontal direction. Can be used for:\n//\n// 1. bitmap with premultiplied alpha\n// 2. bitmap without alpha (all values 255)\n//\n// Notes:\n//\n// - output is transposed\n// - output resolution is ~15 bits per channel(for better precision).\n//\nfunction convolveHor (\n src: MathImageBuffer,\n dest: Uint16Array,\n srcW: number,\n srcH: number,\n destW: number,\n filters: Int16Array\n): void {\n let r, g, b, a\n let filterPtr, filterShift, filterSize\n let srcPtr, srcY, destX, filterVal\n let srcOffset = 0, destOffset = 0\n\n // For each row\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0\n\n // Apply precomputed filters to each destination row point\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++]\n filterSize = filters[filterPtr++]\n\n srcPtr = (srcOffset + (filterShift * 4))|0\n\n r = g = b = a = 0\n\n // Apply the filter to the row to get the destination pixel r, g, b, a\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]\n\n // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n a = (a + filterVal * src[srcPtr + 3])|0\n b = (b + filterVal * src[srcPtr + 2])|0\n g = (g + filterVal * src[srcPtr + 1])|0\n r = (r + filterVal * src[srcPtr])|0\n srcPtr = (srcPtr + 4)|0\n }\n\n // Store 15 bits between passes for better precision\n // Instead of shift to 14 (FIXED_FRAC_BITS), shift to 7 only\n //\n dest[destOffset + 3] = clampNegative(a >> 7)\n dest[destOffset + 2] = clampNegative(b >> 7)\n dest[destOffset + 1] = clampNegative(g >> 7)\n dest[destOffset] = clampNegative(r >> 7)\n destOffset = (destOffset + srcH * 4)|0\n }\n\n destOffset = ((srcY + 1) * 4)|0\n srcOffset = ((srcY + 1) * srcW * 4)|0\n }\n}\n\n// Supplementary method for `convolveHor()`\n//\nfunction convolveVert (\n src: Uint16Array,\n dest: Uint8Array,\n srcW: number,\n srcH: number,\n destW: number,\n filters: Int16Array\n): void {\n let r, g, b, a\n let filterPtr, filterShift, filterSize\n let srcPtr, srcY, destX, filterVal\n let srcOffset = 0, destOffset = 0\n\n // For each row\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0\n\n // Apply precomputed filters to each destination row point\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++]\n filterSize = filters[filterPtr++]\n\n srcPtr = (srcOffset + (filterShift * 4))|0\n\n r = g = b = a = 0\n\n // Apply the filter to the row to get the destination pixel r, g, b, a\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]\n\n // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n a = (a + filterVal * src[srcPtr + 3])|0\n b = (b + filterVal * src[srcPtr + 2])|0\n g = (g + filterVal * src[srcPtr + 1])|0\n r = (r + filterVal * src[srcPtr])|0\n srcPtr = (srcPtr + 4)|0\n }\n\n // Sync with premultiplied version for exact result match\n r >>= 7\n g >>= 7\n b >>= 7\n a >>= 7\n\n // Bring this value back in range + round result.\n //\n dest[destOffset + 3] = clampTo8((a + (1 << 13)) >> 14)\n dest[destOffset + 2] = clampTo8((b + (1 << 13)) >> 14)\n dest[destOffset + 1] = clampTo8((g + (1 << 13)) >> 14)\n dest[destOffset] = clampTo8((r + (1 << 13)) >> 14)\n destOffset = (destOffset + srcH * 4)|0\n }\n\n destOffset = ((srcY + 1) * 4)|0\n srcOffset = ((srcY + 1) * srcW * 4)|0\n }\n}\n\n// Premultiply & convolve image data in horizontal direction. Can be used for:\n//\n// - Any bitmap data, extracted with `.getImageData()` method (with\n// non-premultiplied alpha)\n//\n// For images without alpha channel this method is slower than `convolveHor()`\n//\nfunction convolveHorWithPre (\n src: MathImageBuffer,\n dest: Uint16Array,\n srcW: number,\n srcH: number,\n destW: number,\n filters: Int16Array\n): void {\n let r, g, b, a, alpha\n let filterPtr, filterShift, filterSize\n let srcPtr, srcY, destX, filterVal\n let srcOffset = 0, destOffset = 0\n\n // For each row\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0\n\n // Apply precomputed filters to each destination row point\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++]\n filterSize = filters[filterPtr++]\n\n srcPtr = (srcOffset + (filterShift * 4))|0\n\n r = g = b = a = 0\n\n // Apply the filter to the row to get the destination pixel r, g, b, a\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]\n\n // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n alpha = src[srcPtr + 3]\n a = (a + filterVal * alpha)|0\n b = (b + filterVal * src[srcPtr + 2] * alpha)|0\n g = (g + filterVal * src[srcPtr + 1] * alpha)|0\n r = (r + filterVal * src[srcPtr] * alpha)|0\n srcPtr = (srcPtr + 4)|0\n }\n\n // Premultiply is (* alpha / 255).\n // Postpone division for better performance\n b = (b / 255)|0\n g = (g / 255)|0\n r = (r / 255)|0\n\n // Store 15 bits between passes for better precision\n // Instead of shift to 14 (FIXED_FRAC_BITS), shift to 7 only\n //\n dest[destOffset + 3] = clampNegative(a >> 7)\n dest[destOffset + 2] = clampNegative(b >> 7)\n dest[destOffset + 1] = clampNegative(g >> 7)\n dest[destOffset] = clampNegative(r >> 7)\n destOffset = (destOffset + srcH * 4)|0\n }\n\n destOffset = ((srcY + 1) * 4)|0\n srcOffset = ((srcY + 1) * srcW * 4)|0\n }\n}\n\n// Supplementary method for `convolveHorWithPre()`\n//\nfunction convolveVertWithPre (\n src: Uint16Array,\n dest: Uint8Array,\n srcW: number,\n srcH: number,\n destW: number,\n filters: Int16Array\n): void {\n let r, g, b, a\n let filterPtr, filterShift, filterSize\n let srcPtr, srcY, destX, filterVal\n let srcOffset = 0, destOffset = 0\n\n // For each row\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0\n\n // Apply precomputed filters to each destination row point\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++]\n filterSize = filters[filterPtr++]\n\n srcPtr = (srcOffset + (filterShift * 4))|0\n\n r = g = b = a = 0\n\n // Apply the filter to the row to get the destination pixel r, g, b, a\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]\n\n // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n a = (a + filterVal * src[srcPtr + 3])|0\n b = (b + filterVal * src[srcPtr + 2])|0\n g = (g + filterVal * src[srcPtr + 1])|0\n r = (r + filterVal * src[srcPtr])|0\n srcPtr = (srcPtr + 4)|0\n }\n\n // Downscale to leave room for un-premultiply\n r >>= 7\n g >>= 7\n b >>= 7\n a >>= 7\n\n // Un-premultiply\n a = clampTo8((a + (1 << 13)) >> 14)\n if (a > 0) {\n r = (r * 255 / a)|0\n g = (g * 255 / a)|0\n b = (b * 255 / a)|0\n }\n\n // Bring this value back in range + round result.\n // Shift value = FIXED_FRAC_BITS + 7\n //\n dest[destOffset + 3] = a\n dest[destOffset + 2] = clampTo8((b + (1 << 13)) >> 14)\n dest[destOffset + 1] = clampTo8((g + (1 << 13)) >> 14)\n dest[destOffset] = clampTo8((r + (1 << 13)) >> 14)\n destOffset = (destOffset + srcH * 4)|0\n }\n\n destOffset = ((srcY + 1) * 4)|0\n srcOffset = ((srcY + 1) * srcW * 4)|0\n }\n}\n\nexport {\n convolveHor,\n convolveVert,\n convolveHorWithPre,\n convolveVertWithPre\n}\n","import createFilters from './resize_filter_gen'\nimport { convolveHor, convolveVert, convolveHorWithPre, convolveVertWithPre } from './convolve'\nimport type { MathResizeOptions, MathImageBuffer } from '../mathlib'\n\nfunction hasAlpha (src: MathImageBuffer, width: number, height: number): boolean {\n let ptr = 3\n const len = (width * height * 4)|0\n while (ptr < len) {\n if (src[ptr] !== 255) return true\n ptr = (ptr + 4)|0\n }\n return false\n}\n\nfunction resetAlpha (dst: Uint8Array, width: number, height: number): void {\n let ptr = 3\n const len = (width * height * 4)|0\n while (ptr < len) { dst[ptr] = 0xFF; ptr = (ptr + 4)|0 }\n}\n\nexport default function resize (options: MathResizeOptions): Uint8Array {\n const src = options.src\n const srcW = options.width\n const srcH = options.height\n const destW = options.toWidth\n const destH = options.toHeight\n const scaleX = options.scaleX || options.toWidth / options.width\n const scaleY = options.scaleY || options.toHeight / options.height\n const offsetX = options.offsetX || 0\n const offsetY = options.offsetY || 0\n const dest = options.dest || new Uint8Array(destW * destH * 4)\n\n const filter = typeof options.filter === 'undefined' ? 'mks2013' : options.filter\n const filtersX = createFilters(filter, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(filter, srcH, destH, scaleY, offsetY)\n\n const tmp = new Uint16Array(destW * srcH * 4)\n\n // Autodetect if alpha channel exists, and use appropriate method\n if (hasAlpha(src, srcW, srcH)) {\n convolveHorWithPre(src, tmp, srcW, srcH, destW, filtersX)\n convolveVertWithPre(tmp, dest, srcH, destW, destH, filtersY)\n } else {\n convolveHor(src, tmp, srcW, srcH, destW, filtersX)\n convolveVert(tmp, dest, srcH, destW, destH, filtersY)\n resetAlpha(dest, destW, destH)\n }\n\n return dest\n}\n","import createFilters from './resize_filter_gen'\nimport type { MathResizeOptions, MathWasmContext, MathImageBuffer } from '../mathlib'\n\nfunction hasAlpha (src: MathImageBuffer, width: number, height: number): boolean {\n let ptr = 3\n const len = (width * height * 4)|0\n while (ptr < len) {\n if (src[ptr] !== 255) return true\n ptr = (ptr + 4)|0\n }\n return false\n}\n\nfunction resetAlpha (dst: Uint8Array, width: number, height: number): void {\n let ptr = 3\n const len = (width * height * 4)|0\n while (ptr < len) { dst[ptr] = 0xFF; ptr = (ptr + 4)|0 }\n}\n\nfunction asUint8Array (src: Int16Array): Uint8Array {\n return new Uint8Array(src.buffer, 0, src.byteLength)\n}\n\nlet IS_LE = true\n// should not crash everything on module load in old browsers\ntry {\n IS_LE = ((new Uint32Array((new Uint8Array([1, 0, 0, 0])).buffer))[0] === 1)\n} catch (__) {}\n\nfunction copyInt16asLE (src: Int16Array, target: Uint8Array, target_offset: number): void {\n if (IS_LE) {\n target.set(asUint8Array(src), target_offset)\n return\n }\n\n for (let ptr = target_offset, i = 0; i < src.length; i++) {\n const data = src[i]\n target[ptr++] = data & 0xFF\n target[ptr++] = (data >> 8) & 0xFF\n }\n}\n\nexport default function resize_wasm (this: MathWasmContext, options: MathResizeOptions): Uint8Array {\n const src = options.src\n const srcW = options.width\n const srcH = options.height\n const destW = options.toWidth\n const destH = options.toHeight\n const scaleX = options.scaleX || options.toWidth / options.width\n const scaleY = options.scaleY || options.toHeight / options.height\n const offsetX = options.offsetX || 0.0\n const offsetY = options.offsetY || 0.0\n const dest = options.dest || new Uint8Array(destW * destH * 4)\n\n const filter = typeof options.filter === 'undefined' ? 'mks2013' : options.filter\n const filtersX = createFilters(filter, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(filter, srcH, destH, scaleY, offsetY)\n\n // destination is 0 too.\n const src_offset = 0\n const src_size = Math.max(src.byteLength, dest.byteLength)\n // buffer between convolve passes\n const tmp_offset = this.__align(src_offset + src_size)\n const tmp_size = srcH * destW * 4 * 2 // 2 bytes per channel\n\n const filtersX_offset = this.__align(tmp_offset + tmp_size)\n const filtersY_offset = this.__align(filtersX_offset + filtersX.byteLength)\n const alloc_bytes = filtersY_offset + filtersY.byteLength\n\n const instance = this.__instance('resize', alloc_bytes)\n\n //\n // Fill memory block with data to process\n //\n\n const mem = new Uint8Array(this.__memory!.buffer)\n const mem32 = new Uint32Array(this.__memory!.buffer)\n\n // 32-bit copy is much faster in chrome\n const src32 = new Uint32Array(src.buffer)\n mem32.set(src32)\n\n // We should guarantee LE bytes order. Filters are not big, so\n // speed difference is not significant vs direct .set()\n copyInt16asLE(filtersX, mem, filtersX_offset)\n copyInt16asLE(filtersY, mem, filtersY_offset)\n\n // Now call webassembly method\n // emsdk does method names with '_'\n const fn = (instance.exports.convolveHV || instance.exports._convolveHV) as Function | undefined\n if (!fn) throw new Error('WASM resize function is not available')\n\n if (hasAlpha(src, srcW, srcH)) {\n fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH, 1)\n } else {\n fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH, 0)\n resetAlpha(dest, destW, destH)\n }\n\n //\n // Copy data back to typed array\n //\n\n // 32-bit copy is much faster in chrome\n const dest32 = new Uint32Array(dest.buffer)\n dest32.set(new Uint32Array(this.__memory!.buffer, 0, destH * destW))\n\n return dest\n}\n","// This is autogenerated file from math.wasm, don't edit.\n//\nexport default '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'\n","import fn from './resize'\nimport wasm_fn from './resize_wasm'\nimport wasm_src from './convolve_wasm_base64'\n\nexport default {\n name: 'resize' as const,\n fn,\n wasm_fn,\n wasm_src\n}\n","// Collection of math functions\n//\n// 1. Combine components together\n// 2. Has async init to load wasm modules\n//\nimport { MultiMath } from 'multimath'\n\nimport mm_unsharp_mask from './mm_unsharp_mask'\nimport mm_resize from './mm_resize'\n\nexport type MathFeaturesMap = { js: boolean; wasm: boolean }\nexport type { MultiMathPlugin as MathPlugin } from 'multimath'\nexport type MathImageBuffer = Uint8Array | Uint8ClampedArray\nexport type MathWasmContext = MultiMath\n\nexport type MathResizeFilter = 'box' | 'hamming' | 'lanczos2' | 'lanczos3' | 'mks2013'\n\nexport interface MathResizeOptions {\n src: MathImageBuffer\n width: number\n height: number\n toWidth: number\n toHeight: number\n dest?: Uint8Array\n scaleX: number\n scaleY: number\n offsetX: number\n offsetY: number\n filter: MathResizeFilter\n}\n\nexport interface MathResizeAndUnsharpOptions extends MathResizeOptions {\n unsharpAmount: number\n unsharpRadius: number\n unsharpThreshold: number\n}\n\nexport default class MathLib extends MultiMath {\n declare features: MathFeaturesMap\n declare resize: typeof mm_resize.fn\n declare unsharp_mask: typeof mm_unsharp_mask.fn\n\n constructor (requested_features?: readonly string[]) {\n const __requested_features = requested_features || []\n\n const features = {\n js: __requested_features.indexOf('js') >= 0,\n wasm: __requested_features.indexOf('wasm') >= 0\n }\n\n super(features)\n\n this.features = {\n js: features.js,\n wasm: features.wasm && this.has_wasm()\n }\n\n this.use(mm_unsharp_mask)\n this.use(mm_resize)\n }\n\n resizeAndUnsharp (options: MathResizeAndUnsharpOptions): Uint8Array {\n const result = this.resize(options)\n\n if (options.unsharpAmount) {\n this.unsharp_mask(\n result,\n options.toWidth,\n options.toHeight,\n options.unsharpAmount,\n options.unsharpRadius,\n options.unsharpThreshold\n )\n }\n\n return result\n }\n}\n","const GC_INTERVAL = 100\n\n// Acquired items\nexport interface PoolResource<T> {\n value: T\n release: () => void\n}\n\n// Internal storage format\ninterface PoolResourceDescriptor<T> {\n id: number\n lastUsed: number\n value: T\n destroy: () => void\n}\n\nexport default class Pool<T> {\n create: () => { value: T, destroy: () => void }\n available: Array<PoolResourceDescriptor<T>>\n acquired: Record<number, PoolResourceDescriptor<T>>\n lastId: number\n timeoutId: ReturnType<typeof setTimeout> | 0\n idle: number\n\n constructor (create: () => { value: T, destroy: () => void }, idle?: number) {\n this.create = create\n\n this.available = []\n this.acquired = {}\n this.lastId = 1\n\n this.timeoutId = 0\n this.idle = idle || 2000\n }\n\n acquire (): PoolResource<T> {\n let descriptor: PoolResourceDescriptor<T>\n\n if (this.available.length !== 0) {\n descriptor = this.available.pop() as PoolResourceDescriptor<T>\n } else {\n const init = this.create()\n descriptor = { ...init, id: this.lastId++, lastUsed: 0 }\n }\n this.acquired[descriptor.id] = descriptor\n return { value: descriptor.value, release: () => this.release(descriptor) }\n }\n\n release (descriptor: PoolResourceDescriptor<T>): void {\n delete this.acquired[descriptor.id]\n\n descriptor.lastUsed = Date.now()\n this.available.push(descriptor)\n\n if (this.timeoutId === 0) {\n this.timeoutId = setTimeout(() => this.gc(), GC_INTERVAL)\n }\n }\n\n gc (): void {\n const now = Date.now()\n\n this.available = this.available.filter(descriptor => {\n if (now - descriptor.lastUsed > this.idle) {\n descriptor.destroy()\n return false\n }\n return true\n })\n\n if (this.available.length !== 0) {\n this.timeoutId = setTimeout(() => this.gc(), GC_INTERVAL)\n } else {\n this.timeoutId = 0\n }\n }\n}\n","import type { CibResizeQuality, Filter, Limiter, PicaCanvas } from './types'\n\n// Uses constructor.name — safe because all targets are browser built-ins or\n// native Node.js library classes that minifiers don't rename. If this ever\n// breaks after a toolchain change, fall back to Object.prototype.toString:\n// Object.prototype.toString.call(obj) === '[object HTMLCanvasElement]' etc.\nfunction objClass (obj: unknown): string {\n return (obj as any)?.constructor?.name ?? ''\n}\n\nexport function isCanvas (element: unknown): element is PicaCanvas {\n const cname = objClass(element)\n\n return cname === 'HTMLCanvasElement' ||\n cname === 'OffscreenCanvas' ||\n cname === 'Canvas' /* node-canvas */ ||\n cname === 'CanvasElement' /* @napi-rs/canvas */\n}\n\nexport function isImage (element: unknown): element is HTMLImageElement {\n return objClass(element) === 'HTMLImageElement'\n}\n\nexport function isImageBitmap (element: unknown): element is ImageBitmap {\n return objClass(element) === 'ImageBitmap'\n}\n\nexport function limiter (concurrency: number): Limiter {\n let active = 0\n const queue: Array<() => void> = []\n\n function roll () {\n if (active < concurrency && queue.length) {\n active++\n queue.shift()?.()\n }\n }\n\n return function limit<T> (fn: () => Promise<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n queue.push(() => {\n fn().then(\n result => {\n resolve(result)\n active--\n roll()\n },\n err => {\n reject(err)\n active--\n roll()\n }\n )\n })\n\n roll()\n })\n }\n}\n\nexport function cib_quality_name (num: number): ResizeQuality {\n switch (num) {\n case 0: return 'pixelated'\n case 1: return 'low'\n case 2: return 'medium'\n }\n return 'high'\n}\n\nconst CIB_QUALITY_FILTERS: Filter[] = ['box', 'hamming', 'lanczos2', 'lanczos3']\n\nexport function cib_quality_filter (num: CibResizeQuality): Filter {\n return CIB_QUALITY_FILTERS[num]\n}\n\nexport function is_cib_filter (filter: Filter): boolean {\n return CIB_QUALITY_FILTERS.indexOf(filter) >= 0\n}\n\nexport function filter_to_cib_quality (filter: Filter): CibResizeQuality | undefined {\n const index = CIB_QUALITY_FILTERS.indexOf(filter)\n\n return index >= 0 ? index as CibResizeQuality : undefined\n}\n\ntype ResizeQuality = 'pixelated' | 'low' | 'medium' | 'high'\n","export type Stage = [width: number, height: number]\n\n// Add intermediate resizing steps when scaling down by a very large factor.\n//\n// For example, when resizing 10000x10000 down to 10x10, it'll resize it to\n// 300x300 first.\n//\n// It's needed because tiler has issues when the entire tile is scaled down\n// to a few pixels (1024px source tile with border size 3 should result in\n// at least 3+3+2 = 8px target tile, so max scale factor is 128 here).\n//\n// Also, adding intermediate steps can speed up processing if we use lower\n// quality algorithms for first stages.\n//\n\n// min size = 0 results in infinite loop,\n// min size = 1 can consume large amount of memory\nconst MIN_INNER_TILE_SIZE = 2\n\nconst DEST_TILE_BORDER = 3 // Max possible filter window size\n\nexport default function createStages (\n fromWidth: number,\n fromHeight: number,\n toWidth: number,\n toHeight: number,\n srcTileSize: number\n): Stage[] {\n const scaleX = toWidth / fromWidth\n const scaleY = toHeight / fromHeight\n\n // derived from createRegions equation:\n // innerTileWidth = pixelFloor(srcTileSize * scaleX) - 2 * destTileBorder;\n const minScale = (2 * DEST_TILE_BORDER + MIN_INNER_TILE_SIZE + 1) / srcTileSize\n\n // refuse to scale image multiple times by less than twice each time,\n // it could only happen because of invalid options\n if (minScale > 0.5) return [[toWidth, toHeight]]\n\n const stageCount = Math.ceil(Math.log(Math.min(scaleX, scaleY)) / Math.log(minScale))\n\n // no additional resizes are necessary,\n // stageCount can be zero or be negative when enlarging the image\n if (stageCount <= 1) return [[toWidth, toHeight]]\n\n const result: Stage[] = []\n\n for (let i = 0; i < stageCount; i++) {\n const width = Math.round(\n Math.pow(\n Math.pow(fromWidth, stageCount - i - 1) * Math.pow(toWidth, i + 1),\n 1 / stageCount\n )\n )\n\n const height = Math.round(\n Math.pow(\n Math.pow(fromHeight, stageCount - i - 1) * Math.pow(toHeight, i + 1),\n 1 / stageCount\n )\n )\n\n result.push([width, height])\n }\n\n return result\n}\n","export interface Tile {\n toX: number\n toY: number\n toWidth: number\n toHeight: number\n toInnerX: number\n toInnerY: number\n toInnerWidth: number\n toInnerHeight: number\n offsetX: number\n offsetY: number\n scaleX: number\n scaleY: number\n x: number\n y: number\n width: number\n height: number\n}\n\nexport interface TilerOptions {\n width: number\n height: number\n srcTileSize: number\n toWidth: number\n toHeight: number\n destTileBorder: number\n}\n\n// Split original image into multiple 1024x1024 chunks to reduce memory usage\n// (images have to be unpacked into typed arrays for resizing) and allow\n// parallel processing of multiple tiles at a time.\n//\n\n/*\n * pixelFloor and pixelCeil are modified versions of Math.floor and Math.ceil\n * functions which take into account floating point arithmetic errors.\n * Those errors can cause undesired increments/decrements of sizes and offsets:\n * Math.ceil(36 / (36 / 500)) = 501\n * pixelCeil(36 / (36 / 500)) = 500\n */\n\nconst PIXEL_EPSILON = 1e-5\n\nfunction pixelFloor (x: number): number {\n const nearest = Math.round(x)\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) { return nearest }\n return Math.floor(x)\n}\n\nfunction pixelCeil (x: number): number {\n const nearest = Math.round(x)\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) { return nearest }\n return Math.ceil(x)\n}\n\nexport default function createRegions (options: TilerOptions): Tile[] {\n const scaleX = options.toWidth / options.width\n const scaleY = options.toHeight / options.height\n\n const innerTileWidth = pixelFloor(options.srcTileSize * scaleX) - 2 * options.destTileBorder\n const innerTileHeight = pixelFloor(options.srcTileSize * scaleY) - 2 * options.destTileBorder\n\n // prevent infinite loop, this should never happen\n if (innerTileWidth < 1 || innerTileHeight < 1) {\n throw new Error('Internal error in pica: target tile width/height is too small.')\n }\n\n let x, y\n let innerX, innerY, toTileWidth, toTileHeight\n const tiles: Tile[] = []\n let tile: Tile\n\n // we go top-to-bottom instead of left-to-right so the image is displayed\n // from top to bottom in the browser\n for (innerY = 0; innerY < options.toHeight; innerY += innerTileHeight) {\n for (innerX = 0; innerX < options.toWidth; innerX += innerTileWidth) {\n x = innerX - options.destTileBorder\n if (x < 0) { x = 0 }\n toTileWidth = innerX + innerTileWidth + options.destTileBorder - x\n if (x + toTileWidth >= options.toWidth) {\n toTileWidth = options.toWidth - x\n }\n\n y = innerY - options.destTileBorder\n if (y < 0) { y = 0 }\n toTileHeight = innerY + innerTileHeight + options.destTileBorder - y\n if (y + toTileHeight >= options.toHeight) {\n toTileHeight = options.toHeight - y\n }\n\n tile = {\n toX: x,\n toY: y,\n toWidth: toTileWidth,\n toHeight: toTileHeight,\n\n toInnerX: innerX,\n toInnerY: innerY,\n toInnerWidth: innerTileWidth,\n toInnerHeight: innerTileHeight,\n\n offsetX: x / scaleX - pixelFloor(x / scaleX),\n offsetY: y / scaleY - pixelFloor(y / scaleY),\n scaleX,\n scaleY,\n\n x: pixelFloor(x / scaleX),\n y: pixelFloor(y / scaleY),\n width: pixelCeil(toTileWidth / scaleX),\n height: pixelCeil(toTileHeight / scaleY)\n }\n\n tiles.push(tile)\n }\n }\n\n return tiles\n}\n","import type { PicaCanvas, PicaCanvasCtx } from './types'\n\nexport interface SupportedFeatures {\n canvas: boolean\n offscreen_canvas: boolean\n may_be_worker: boolean\n create_image_bitmap: boolean\n safari_put_image_data_fix: boolean\n bug_canvas_orientation_region: boolean\n bug_image_bitmap_orientation_region: boolean\n cib_resize: boolean\n}\n\n// 3x2 JPEG with EXIF orientation 6 (rotate 90deg clockwise when decoded).\n//\n// Stored pixels, before orientation (Black, White):\n//\n// B W B\n// B B B\n//\n// After orientation is applied, decoded image should be 2x3:\n//\n// B B\n// B W <- pixel at (1, 1) should be white if region crop is correct\n// B B\n//\n// If crop coordinates are applied before orientation, region (1, 1, 1, 1)\n// returns black instead. The checks below use this to detect region/orientation\n// bugs in canvas drawImage() and createImageBitmap().\nconst ORIENTED_JPEG_BASE64 =\n '/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/4AAQskZJRgABAQAAA' +\n 'QABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCw' +\n 'kJDRENDg8QEBEQCgwSExIQEw8QEBD/wAALCAACAAMBAREA/8QAFAABAAAAAAAAAAAAAAAA' +\n 'AAAACf/EABsQAAMBAQADAAAAAAAAAAAAAAECAwQFABEx/9oACAEBAAA/AC06fW6va0ps' +\n '7PT179E88MiV02arrCEkjGQZiSEnKc5ovxURVHoADz//2Q=='\n\nconst features: SupportedFeatures = {\n canvas: false,\n offscreen_canvas: false,\n may_be_worker: false,\n create_image_bitmap: false,\n safari_put_image_data_fix: false,\n bug_canvas_orientation_region: true,\n bug_image_bitmap_orientation_region: true,\n cib_resize: false\n}\n\nlet checked = false\nlet checking: Promise<SupportedFeatures> | null = null\n\nfunction check_canvas (): boolean {\n if (typeof document === 'undefined' || !document.createElement) return false\n\n try {\n const canvas = document.createElement('canvas')\n canvas.width = 2\n canvas.height = 1\n\n const ctx = canvas.getContext('2d')!\n\n // Fingerprinting protection can randomize readback.\n // In that case we can not rely on canvas pixel data.\n let d = ctx.createImageData(2, 1)\n\n d.data[0] = 12; d.data[1] = 23; d.data[2] = 34; d.data[3] = 255\n d.data[4] = 45; d.data[5] = 56; d.data[6] = 67; d.data[7] = 255\n ctx.putImageData(d, 0, 0)\n d = ctx.getImageData(0, 0, 2, 1)\n\n return d.data[0] === 12 && d.data[1] === 23 && d.data[2] === 34 && d.data[3] === 255 &&\n d.data[4] === 45 && d.data[5] === 56 && d.data[6] === 67 && d.data[7] === 255\n } catch (__) {\n return false\n }\n}\n\nfunction check_offscreen_canvas (): boolean {\n if (typeof OffscreenCanvas === 'undefined') return false\n\n try {\n const canvas = new OffscreenCanvas(2, 1)\n const ctx = canvas.getContext('2d')!\n\n // Fingerprinting protection can randomize readback.\n // In that case we can not rely on canvas pixel data.\n let d = ctx.createImageData(2, 1)\n\n d.data[0] = 12; d.data[1] = 23; d.data[2] = 34; d.data[3] = 255\n d.data[4] = 45; d.data[5] = 56; d.data[6] = 67; d.data[7] = 255\n ctx.putImageData(d, 0, 0)\n d = ctx.getImageData(0, 0, 2, 1)\n\n return d.data[0] === 12 && d.data[1] === 23 && d.data[2] === 34 && d.data[3] === 255 &&\n d.data[4] === 45 && d.data[5] === 56 && d.data[6] === 67 && d.data[7] === 255\n } catch (__) {\n return false\n }\n}\n\nfunction check_create_image_bitmap (): boolean {\n return typeof createImageBitmap !== 'undefined'\n}\n\nfunction check_may_be_worker (): boolean {\n return typeof Worker !== 'undefined' &&\n // Filter out IE <= 11 for sure\n (typeof URL !== 'undefined' && !!URL.createObjectURL)\n}\n\nfunction check_safari_put_image_data_fix (): boolean {\n try {\n return !!(typeof navigator !== 'undefined' &&\n navigator.userAgent &&\n navigator.userAgent.indexOf('Safari') >= 0 &&\n navigator.userAgent.indexOf('Chrome') < 0)\n } catch (__) {\n return false\n }\n}\n\nfunction check_bug_canvas_orientation_region_async (): Promise<boolean> {\n return Promise.resolve().then(() => {\n const canOffscreenCanvas = check_offscreen_canvas() &&\n check_create_image_bitmap() &&\n typeof Blob !== 'undefined' &&\n typeof atob !== 'undefined'\n\n if (canOffscreenCanvas) {\n const binary = atob(ORIENTED_JPEG_BASE64)\n const bytes = new Uint8Array(binary.length)\n\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n\n return createImageBitmap(new Blob([bytes], { type: 'image/jpeg' }))\n .then(bitmap => {\n const canvas = new OffscreenCanvas(1, 1)\n\n try {\n const ctx = canvas.getContext('2d')!\n ctx.drawImage(bitmap, 1, 1, 1, 1, 0, 0, 1, 1)\n\n return ctx.getImageData(0, 0, 1, 1).data[0] < 240\n } finally {\n bitmap.close()\n }\n })\n }\n\n if (check_canvas() && typeof Image !== 'undefined') {\n return new Promise<boolean>(resolve => {\n const image = new Image()\n\n image.onload = () => {\n try {\n const canvas = document.createElement('canvas')\n canvas.width = 1\n canvas.height = 1\n\n const ctx = canvas.getContext('2d')!\n ctx.drawImage(image, 1, 1, 1, 1, 0, 0, 1, 1)\n\n resolve(ctx.getImageData(0, 0, 1, 1).data[0] < 240)\n } catch (__) {\n resolve(true)\n }\n }\n\n image.onerror = () => resolve(true)\n image.src = `data:image/jpeg;base64,${ORIENTED_JPEG_BASE64}`\n })\n }\n\n return true\n })\n .catch(() => true)\n}\n\nfunction check_bug_image_bitmap_orientation_region_async (): Promise<boolean> {\n return Promise.resolve().then(() => {\n if (!features.create_image_bitmap && !check_create_image_bitmap()) return true\n if (typeof Blob === 'undefined' || typeof atob === 'undefined') return true\n\n const canOffscreenCanvas = check_offscreen_canvas()\n const canCanvas = check_canvas()\n\n if (!canOffscreenCanvas && !canCanvas) return true\n\n const binary = atob(ORIENTED_JPEG_BASE64)\n const bytes = new Uint8Array(binary.length)\n\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n\n return createImageBitmap(new Blob([bytes], { type: 'image/jpeg' }))\n .then(imageBitmap => createImageBitmap(imageBitmap, 1, 1, 1, 1)\n .then(bitmap => {\n let canvas: PicaCanvas\n\n if (canOffscreenCanvas) {\n canvas = new OffscreenCanvas(1, 1)\n } else {\n canvas = document.createElement('canvas')\n canvas.width = 1\n canvas.height = 1\n }\n\n try {\n const ctx = canvas.getContext('2d') as PicaCanvasCtx\n ctx.drawImage(bitmap, 0, 0)\n\n return bitmap.width !== 1 || bitmap.height !== 1 ||\n ctx.getImageData(0, 0, 1, 1).data[0] < 240\n } finally {\n imageBitmap.close()\n bitmap.close()\n }\n }, () => {\n imageBitmap.close()\n return true\n }))\n })\n .catch(() => true)\n}\n\nfunction check_cib_resize_async (): Promise<boolean> {\n return Promise.resolve().then(() => {\n if (!check_create_image_bitmap()) return false\n\n const SRC_SIZE = 20\n const DST_SIZE = 5\n\n let canvas: PicaCanvas | null\n\n if (features.canvas || check_canvas()) {\n canvas = document.createElement('canvas')\n canvas.width = SRC_SIZE\n canvas.height = SRC_SIZE\n } else if (features.offscreen_canvas || check_offscreen_canvas()) {\n canvas = new OffscreenCanvas(SRC_SIZE, SRC_SIZE)\n // Chrome fails to createImageBitmap() from canvas without drawing\n // anything on it.\n const ctx = canvas.getContext('2d')!\n ctx.clearRect(0, 0, SRC_SIZE, SRC_SIZE)\n } else {\n return false\n }\n\n return createImageBitmap(canvas, 0, 0, SRC_SIZE, SRC_SIZE, {\n resizeWidth: DST_SIZE,\n resizeHeight: DST_SIZE,\n resizeQuality: 'high'\n })\n .then(bitmap => {\n const status = bitmap.width === DST_SIZE && !!bitmap.close\n\n if (bitmap.close) bitmap.close()\n canvas = null\n return status\n })\n })\n .catch(() => false)\n}\n\nexport function get_supported_features (): Promise<SupportedFeatures> {\n if (checked) return Promise.resolve(Object.assign({}, features))\n if (checking) return checking.then(() => Object.assign({}, features))\n\n features.canvas = check_canvas()\n features.offscreen_canvas = check_offscreen_canvas()\n features.may_be_worker = check_may_be_worker()\n features.create_image_bitmap = check_create_image_bitmap()\n features.safari_put_image_data_fix = check_safari_put_image_data_fix()\n\n const bugCanvasOrientationRegion = check_bug_canvas_orientation_region_async()\n .then(result => { features.bug_canvas_orientation_region = result })\n .catch(() => {})\n\n const bugImageBitmapOrientationRegion = check_bug_image_bitmap_orientation_region_async()\n .then(result => { features.bug_image_bitmap_orientation_region = result })\n .catch(() => {})\n\n const cibResize = check_cib_resize_async()\n .then(result => { features.cib_resize = result })\n .catch(() => {})\n\n checking = Promise.all([\n bugCanvasOrientationRegion,\n bugImageBitmapOrientationRegion,\n cibResize\n ]).then(() => {\n checked = true\n checking = null\n return Object.assign({}, features)\n }, err => {\n checking = null\n throw err\n })\n\n return checking\n}\n","import MathLib, { type MathResizeAndUnsharpOptions } from './mathlib'\nimport Pool from './pool'\nimport * as utils from './utils'\nimport createStages from './stepper'\nimport createRegions, { type Tile } from './tiler'\nimport * as supported_features from './supported_features'\nimport type {\n Capabilities,\n CreateCanvasPreference,\n PicaFeaturesFlat,\n Filter,\n Limiter,\n PicaCanvas,\n PicaCanvasCtx,\n PicaOptions,\n PicaSource,\n ResizeBufferOptions,\n ResizeContext,\n ResizeFeaturesMap,\n ResizeParams,\n TileResizeJob,\n TileResizeJobBase,\n ResizeOptions,\n ResizeResult,\n ResolvedPicaOptions,\n StageEnv,\n WorkerFeaturesResult,\n WorkerMethod,\n WorkerResizePayload\n} from './types'\n\nexport type {\n PicaFeaturesFlat,\n Filter,\n PicaCanvas,\n PicaOptions,\n PicaSource,\n ResizeBufferOptions,\n ResizeOptions,\n CibResizeQuality\n} from './types'\n\ndeclare const __PICA_WORKER_SRC__: string | undefined\n\nconst WORKER_SRC = typeof __PICA_WORKER_SRC__ !== 'undefined' ? __PICA_WORKER_SRC__ : ''\n\nlet concurrency = 1\nif (typeof navigator !== 'undefined') {\n concurrency = Math.min(navigator.hardwareConcurrency || 1, 4)\n}\n\nconst DEFAULT_PICA_OPTS: ResolvedPicaOptions = {\n tile: 1024,\n concurrency,\n features: ['js', 'wasm', 'ww'],\n idle: 2000,\n}\n\nconst DEFAULT_RESIZE_OPTS = {\n filter: 'mks2013',\n unsharpAmount: 0,\n unsharpRadius: 0.0,\n unsharpThreshold: 0\n}\n\n// //////////////////////////////////////////////////////////////////////////////\n// API methods\n\nexport class Pica {\n private options: ResolvedPicaOptions\n private __limit: Limiter\n private resize_features: ResizeFeaturesMap\n private __workersPool: Pool<Worker> | null\n private capabilities: Capabilities\n private __requested_features: PicaFeaturesFlat\n private __mathlib: MathLib | null\n private __initPromise?: Promise<this>\n\n constructor (options?: PicaOptions) {\n this.options = Object.assign({}, DEFAULT_PICA_OPTS, options || {})\n\n const workerRequested = this.options.features.indexOf('ww') >= 0 || this.options.features.indexOf('all') >= 0\n\n if (workerRequested && !this.options.workerURL && !WORKER_SRC) {\n throw new Error('Pica: cannot use WebWorker without workerURL')\n }\n\n this.__limit = utils.limiter(this.options.concurrency)\n\n // List of enabled resize methods, according to options & browser/node.js\n this.resize_features = {\n js: false, // pure JS implementation, can be disabled for testing\n wasm: false, // webassembly implementation for heavy functions\n cib: false, // resize via createImageBitmap (only FF at this moment)\n ww: false // webworkers\n }\n\n this.__workersPool = null\n this.capabilities = {\n worker: false,\n ww_offscreen_canvas: false,\n canvas: false,\n offscreen_canvas: false,\n may_be_worker: false,\n create_image_bitmap: false,\n safari_put_image_data_fix: false,\n bug_canvas_orientation_region: true,\n bug_image_bitmap_orientation_region: true,\n cib_resize: false\n }\n\n // Store requested features for webworkers\n this.__requested_features = []\n\n this.__mathlib = null\n }\n\n init (): Promise<this> {\n if (this.__initPromise) return this.__initPromise\n\n this.__initPromise = this.__init()\n\n return this.__initPromise\n }\n\n private async __init (): Promise<this> {\n let features = this.options.features.slice()\n\n if (features.indexOf('all') >= 0) {\n features = ['cib', 'wasm', 'js', 'ww']\n }\n\n this.__requested_features = features\n\n this.__mathlib = new MathLib(features)\n\n const result = await supported_features.get_supported_features()\n Object.assign(this.capabilities, result)\n\n if (this.capabilities.cib_resize && features.indexOf('cib') >= 0) {\n this.resize_features.cib = true\n }\n\n // Check WebWorker support if requested\n if (this.capabilities.may_be_worker && features.indexOf('ww') >= 0 && (WORKER_SRC || this.options.workerURL)) {\n this.__workersPool = new Pool(() => this.__createWorkerSlot(), this.options.idle)\n }\n\n if (this.__workersPool) {\n try {\n const result = await this.__invokeWorker<WorkerFeaturesResult>('get_supported_features')\n const resultData = result && result.data\n if (resultData) {\n this.capabilities.worker = true\n this.resize_features.ww = true\n this.capabilities.ww_offscreen_canvas = !!resultData.offscreen_canvas\n }\n } catch (__) {}\n }\n\n const mathlib = await this.__mathlib.init()\n // Copy detected resize methods\n Object.assign(this.resize_features, mathlib.features)\n\n return this\n }\n\n createCanvas (width: number, height: number, preferOffscreen?: CreateCanvasPreference): PicaCanvas {\n if (preferOffscreen && this.capabilities.offscreen_canvas) {\n return new OffscreenCanvas(width, height)\n }\n\n if (this.capabilities.canvas) {\n const canvas = document.createElement('canvas')\n canvas.width = width\n canvas.height = height\n return canvas\n }\n\n if (this.capabilities.ww_offscreen_canvas) {\n return new OffscreenCanvas(width, height)\n }\n\n throw new Error('Pica: cannot create canvas')\n }\n\n private __createWorkerSlot (): { value: Worker, destroy: () => void } {\n if (this.options.workerURL) {\n const worker = new Worker(String(this.options.workerURL))\n return { value: worker, destroy () { worker.terminate() } }\n }\n\n if (WORKER_SRC) {\n const objectURL = window.URL.createObjectURL(new Blob([WORKER_SRC], { type: 'text/javascript' }))\n const worker = new Worker(objectURL)\n return {\n value: worker,\n destroy () {\n worker.terminate()\n if (typeof window !== 'undefined') {\n window.URL?.revokeObjectURL?.(objectURL)\n }\n }\n }\n }\n\n throw new Error('Pica: no worker source available')\n }\n\n // Call resizer in webworker or locally, depending on config\n private __invokeWorker<TResult> (\n method: WorkerMethod,\n payload?: Record<string, unknown>,\n transfer?: Transferable[],\n opts?: { cancelToken?: Promise<unknown> }\n ): Promise<TResult> {\n return new Promise((resolve, reject) => {\n const w = this.__workersPool!.acquire()\n\n if (opts && opts.cancelToken) opts.cancelToken.catch(err => reject(err))\n\n w.value.onmessage = ev => {\n w.release()\n\n if (ev.data.err) reject(ev.data.err)\n else resolve(ev.data)\n }\n\n w.value.postMessage(Object.assign({ method }, payload || {}), transfer || [])\n })\n }\n\n private async __invokeResize (tileJob: TileResizeJob, ctx: ResizeContext): Promise<ResizeResult> {\n await Promise.resolve()\n\n if (!this.resize_features.ww) {\n // not possible to have ImageBitmap here if user disabled WW\n if (tileJob.kind !== 'array') throw new Error('Pica: resize tile data is missing')\n\n const mathOpts: MathResizeAndUnsharpOptions = {\n src: tileJob.src,\n width: tileJob.width,\n height: tileJob.height,\n toWidth: tileJob.toWidth,\n toHeight: tileJob.toHeight,\n scaleX: tileJob.scaleX,\n scaleY: tileJob.scaleY,\n offsetX: tileJob.offsetX,\n offsetY: tileJob.offsetY,\n filter: tileJob.filter,\n unsharpAmount: tileJob.unsharpAmount,\n unsharpRadius: tileJob.unsharpRadius,\n unsharpThreshold: tileJob.unsharpThreshold\n }\n\n return { kind: 'array', data: this.__mathlib!.resizeAndUnsharp(mathOpts) }\n }\n\n const transfer = []\n\n if (tileJob.kind === 'array') transfer.push(tileJob.src.buffer)\n else transfer.push(tileJob.src)\n\n return this.__invokeWorker<ResizeResult>(\n 'resize',\n {\n job: tileJob,\n features: this.__requested_features\n } satisfies Omit<WorkerResizePayload, 'method'>,\n transfer,\n ctx\n )\n }\n\n // this function can return promise if createImageBitmap is used\n private __extractTileData (\n tile: Tile,\n from: PicaSource,\n stageEnv: StageEnv,\n extractTo: TileResizeJobBase\n ): TileResizeJob {\n if (this.resize_features.ww && this.capabilities.ww_offscreen_canvas) {\n this.debug('Create tile imageBitmap')\n\n const tileCanvas = this.createCanvas(tile.width, tile.height, { preferOffscreen: true })\n const tileCtx = tileCanvas.getContext('2d') as PicaCanvasCtx\n\n tileCtx.drawImage(stageEnv.srcImageBitmap || from,\n tile.x, tile.y, tile.width, tile.height,\n 0, 0, tile.width, tile.height)\n\n if (!('transferToImageBitmap' in tileCanvas)) {\n throw new Error('Pica: offscreen canvas is not available for worker transfer')\n }\n\n return Object.assign({}, extractTo, {\n kind: 'bitmap' as const,\n src: tileCanvas.transferToImageBitmap()\n })\n\n // Direct region extraction, intentionally disabled. This can be faster,\n // but has known EXIF orientation bugs in some browsers.\n //\n // return createImageBitmap(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height)\n // .then(bitmap => {\n // extractTo.src = bitmap;\n // return extractTo;\n // });\n }\n\n // Extract tile RGBA buffer, depending on input type\n if (utils.isCanvas(from)) {\n if (!stageEnv.srcCtx) stageEnv.srcCtx = from.getContext('2d') as PicaCanvasCtx\n\n // If input is Canvas - extract region data directly\n this.debug('Get tile pixel data')\n return Object.assign({}, extractTo, {\n kind: 'array' as const,\n src: stageEnv.srcCtx.getImageData(tile.x, tile.y, tile.width, tile.height).data\n })\n }\n\n // If input is Image or decoded to ImageBitmap,\n // draw region to temporary canvas and extract data from it\n //\n // Note! Attempt to reuse this canvas causes significant slowdown in chrome\n //\n this.debug('Draw tile imageBitmap/image to temporary canvas')\n\n const tmpCanvas = this.createCanvas(tile.width, tile.height, { preferOffscreen: true })\n\n const tmpCtx = tmpCanvas.getContext('2d') as PicaCanvasCtx\n tmpCtx.globalCompositeOperation = 'copy'\n tmpCtx.drawImage(stageEnv.srcImageBitmap || from,\n tile.x, tile.y, tile.width, tile.height,\n 0, 0, tile.width, tile.height)\n\n this.debug('Get tile pixel data')\n\n const src = tmpCtx.getImageData(0, 0, tile.width, tile.height).data\n\n // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n tmpCanvas.width = tmpCanvas.height = 0\n\n return Object.assign({}, extractTo, {\n kind: 'array' as const,\n src\n })\n }\n\n private __landTileData (tile: Tile, result: ResizeResult, stageEnv: StageEnv): null {\n if (result.kind === 'bitmap') {\n stageEnv.toCtx!.drawImage(result.data, tile.toX, tile.toY)\n result.data.close()\n return null\n }\n\n this.debug('Draw tile')\n\n const toImageData = stageEnv.toCtx!.createImageData(tile.toWidth, tile.toHeight)\n toImageData.data.set(result.data)\n\n if (this.capabilities.safari_put_image_data_fix) {\n // Safari draws thin white stripes between tiles without this fix\n stageEnv.toCtx!.putImageData(toImageData, tile.toX, tile.toY,\n tile.toInnerX - tile.toX, tile.toInnerY - tile.toY,\n tile.toInnerWidth + 1e-5, tile.toInnerHeight + 1e-5)\n } else {\n stageEnv.toCtx!.putImageData(toImageData, tile.toX, tile.toY,\n tile.toInnerX - tile.toX, tile.toInnerY - tile.toY,\n tile.toInnerWidth, tile.toInnerHeight)\n }\n\n return null\n }\n\n private async __tileAndResize (\n from: PicaSource,\n to: PicaCanvas,\n resizeParams: ResizeParams,\n ctx: ResizeContext\n ): Promise<PicaCanvas> {\n const stageEnv: StageEnv = {\n srcCtx: null,\n srcImageBitmap: null,\n isImageBitmapReused: false,\n toCtx: null\n }\n\n const processTile = (tile: Tile) => this.__limit(async () => {\n if (ctx.canceled) return ctx.cancelToken\n\n const tileJob: TileResizeJobBase = {\n width: tile.width,\n height: tile.height,\n toWidth: tile.toWidth,\n toHeight: tile.toHeight,\n scaleX: tile.scaleX,\n scaleY: tile.scaleY,\n offsetX: tile.offsetX,\n offsetY: tile.offsetY,\n filter: resizeParams.filter,\n unsharpAmount: resizeParams.unsharpAmount,\n unsharpRadius: resizeParams.unsharpRadius,\n unsharpThreshold: resizeParams.unsharpThreshold\n }\n\n this.debug('Invoke resize math')\n\n const extractedTileJob = await this.__extractTileData(tile, from, stageEnv, tileJob)\n\n this.debug('Invoke resize math')\n const result = await this.__invokeResize(extractedTileJob, ctx)\n\n if (ctx.canceled) return ctx.cancelToken\n return this.__landTileData(tile, result, stageEnv)\n })\n\n // Need to normalize data source first. It can be canvas or image.\n // If image - try to decode in background if possible\n await Promise.resolve()\n\n stageEnv.toCtx = to.getContext('2d') as PicaCanvasCtx\n\n if (utils.isCanvas(from)) {\n // Source is ready as-is.\n } else if (utils.isImageBitmap(from)) {\n stageEnv.srcImageBitmap = from\n stageEnv.isImageBitmapReused = true\n } else if (utils.isImage(from)) {\n // try to decode image in background for faster next operations;\n // if we're using offscreen canvas, cib is called per tile, so not needed here\n if (this.capabilities.create_image_bitmap) {\n this.debug('Decode image via createImageBitmap')\n\n // Suppress error to use fallback, if method fails\n // https://github.com/nodeca/pica/issues/190\n try {\n stageEnv.srcImageBitmap = await createImageBitmap(from)\n } catch (__) {}\n }\n } else {\n throw new Error('Pica: \".from\" should be Image, Canvas or ImageBitmap')\n }\n\n if (ctx.canceled) return ctx.cancelToken as Promise<PicaCanvas>\n\n this.debug('Calculate tiles')\n\n //\n // Here we are with \"normalized\" source,\n // follow to tiling\n //\n\n const regions = createRegions({\n width: resizeParams.width,\n height: resizeParams.height,\n srcTileSize: this.options.tile,\n toWidth: resizeParams.toWidth,\n toHeight: resizeParams.toHeight,\n destTileBorder: Math.ceil(Math.max(3, 2.5 * resizeParams.unsharpRadius | 0))\n })\n\n const jobs = regions.map(tile => processTile(tile))\n\n function cleanup (stageEnv: StageEnv) {\n if (stageEnv.srcImageBitmap) {\n if (!stageEnv.isImageBitmapReused) stageEnv.srcImageBitmap.close()\n stageEnv.srcImageBitmap = null\n }\n }\n\n this.debug('Process tiles')\n\n try {\n await Promise.all(jobs)\n this.debug('Finished!')\n cleanup(stageEnv)\n return to\n } catch (err) {\n cleanup(stageEnv)\n throw err\n }\n }\n\n private async __planStagesAndResize (\n from: PicaSource,\n to: PicaCanvas,\n resizeParams: ResizeParams,\n ctx: ResizeContext\n ): Promise<PicaCanvas> {\n let src: PicaSource = from\n let srcWidth = resizeParams.width\n let srcHeight = resizeParams.height\n\n const stages = createStages(\n resizeParams.width,\n resizeParams.height,\n resizeParams.toWidth,\n resizeParams.toHeight,\n this.options.tile\n )\n\n while (stages.length > 0) {\n if (ctx.canceled) return ctx.cancelToken as Promise<PicaCanvas>\n\n const [toWidth, toHeight] = stages.shift()!\n const isLastStage = stages.length === 0\n\n // Optimization for legacy filters -\n // only use user-defined quality for the last stage,\n // use simpler (Hamming) filter for the first stages where\n // scale factor is large enough (more than 2-3)\n //\n // For advanced filters (mks2013 and custom) - skip optimization,\n // because need to apply sharpening every time\n let filter: Filter\n if (isLastStage || !utils.is_cib_filter(resizeParams.filter)) filter = resizeParams.filter\n else if (resizeParams.filter === 'box') filter = 'box'\n else filter = 'hamming'\n\n const stageParams: ResizeParams = { ...resizeParams, filter, width: srcWidth, height: srcHeight, toWidth, toHeight }\n const dest = isLastStage ? to : this.createCanvas(toWidth, toHeight, { preferOffscreen: true })\n\n // Previous intermediate canvas (not the original `from`) can be freed after use\n const prevTmp = src !== from ? src as PicaCanvas : undefined\n\n try {\n await this.__tileAndResize(src, dest, stageParams, ctx)\n } finally {\n // Safari 12 workaround: https://github.com/nodeca/pica/issues/199\n if (prevTmp) prevTmp.width = prevTmp.height = 0\n }\n\n src = dest\n srcWidth = toWidth\n srcHeight = toHeight\n }\n\n return to\n }\n\n private async __resizeViaCreateImageBitmap (\n from: PicaSource,\n to: PicaCanvas,\n resizeParams: ResizeParams,\n ctx: ResizeContext\n ): Promise<PicaCanvas> {\n let toCtx: PicaCanvasCtx | null = to.getContext('2d') as PicaCanvasCtx\n\n this.debug('Resize via createImageBitmap()')\n\n const imageBitmap = await createImageBitmap(from, {\n resizeWidth: resizeParams.toWidth,\n resizeHeight: resizeParams.toHeight,\n resizeQuality: utils.cib_quality_name(utils.filter_to_cib_quality(resizeParams.filter) ?? 3)\n })\n if (ctx.canceled) return ctx.cancelToken as Promise<PicaCanvas>\n\n // if no unsharp - draw directly to output canvas\n if (!resizeParams.unsharpAmount) {\n toCtx.drawImage(imageBitmap, 0, 0)\n imageBitmap.close()\n toCtx = null\n\n this.debug('Finished!')\n\n return to\n }\n\n this.debug('Unsharp result')\n\n let tmpCanvas: PicaCanvas | null = this.createCanvas(resizeParams.toWidth, resizeParams.toHeight)\n\n let tmpCtx: PicaCanvasCtx | null = tmpCanvas.getContext('2d') as PicaCanvasCtx\n\n tmpCtx.drawImage(imageBitmap, 0, 0)\n imageBitmap.close()\n\n let iData: ImageData | null = tmpCtx.getImageData(0, 0, resizeParams.toWidth, resizeParams.toHeight)\n\n this.__mathlib!.unsharp_mask(\n iData.data,\n resizeParams.toWidth,\n resizeParams.toHeight,\n resizeParams.unsharpAmount,\n resizeParams.unsharpRadius,\n resizeParams.unsharpThreshold\n )\n\n toCtx.putImageData(iData, 0, 0)\n\n // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n tmpCanvas.width = tmpCanvas.height = 0\n\n iData = tmpCtx = tmpCanvas = toCtx = null\n\n this.debug('Finished!')\n\n return to\n }\n\n async resize<TCanvas extends PicaCanvas> (\n from: PicaSource,\n to: TCanvas,\n options?: ResizeOptions\n ): Promise<TCanvas> {\n this.debug('Start resize...')\n\n const requested: ResizeOptions = {}\n\n if (options) {\n Object.assign(requested, options)\n }\n\n let filter: Filter = (requested.filter || DEFAULT_RESIZE_OPTS.filter) as Filter\n\n // Legacy `.quality` option\n if (Object.prototype.hasOwnProperty.call(requested, 'quality')) {\n const quality = requested.quality\n if (typeof quality !== 'number' || quality < 0 || quality > 3) {\n throw new Error(`Pica: .quality should be [0..3], got ${quality}`)\n }\n filter = utils.cib_quality_filter(quality)\n }\n\n const resizeParams: ResizeParams = {\n filter,\n unsharpAmount: requested.unsharpAmount || DEFAULT_RESIZE_OPTS.unsharpAmount,\n unsharpRadius: requested.unsharpRadius || DEFAULT_RESIZE_OPTS.unsharpRadius,\n unsharpThreshold: requested.unsharpThreshold || DEFAULT_RESIZE_OPTS.unsharpThreshold,\n width: utils.isImage(from) ? from.naturalWidth : from.width,\n height: utils.isImage(from) ? from.naturalHeight : from.height,\n toWidth: to.width,\n toHeight: to.height\n }\n\n if (resizeParams.unsharpRadius > 2) resizeParams.unsharpRadius = 2\n\n // Prevent stepper from infinite loop\n if (to.width === 0 || to.height === 0) {\n return Promise.reject(new Error(`Invalid output size: ${to.width}x${to.height}`))\n }\n\n const ctx: ResizeContext = {\n cancelToken: requested.cancelToken,\n canceled: false\n }\n\n if (ctx.cancelToken) {\n // Wrap cancelToken to avoid successive resolve & set flag\n ctx.cancelToken = ctx.cancelToken.then(\n data => { ctx.canceled = true; throw data },\n err => { ctx.canceled = true; throw err }\n )\n }\n\n await this.init()\n\n if (ctx.canceled) return ctx.cancelToken as Promise<TCanvas>\n\n // createImageBitmap doesn't work for images (Image, ImageBitmap) with\n // Exif orientation in Chrome. Enforce canvas use for such inputs.\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n if (this.capabilities.bug_image_bitmap_orientation_region &&\n (utils.isImage(from) || (utils.isImageBitmap(from)))) {\n const tmpCanvas = this.createCanvas(resizeParams.width, resizeParams.height)\n const tmpCtx = tmpCanvas.getContext('2d') as PicaCanvasCtx\n tmpCtx.drawImage(from, 0, 0)\n from = tmpCanvas\n }\n\n // if createImageBitmap supports resize, just do it and return\n if (this.resize_features.cib) {\n if (utils.is_cib_filter(resizeParams.filter)) {\n return this.__resizeViaCreateImageBitmap(from, to, resizeParams, ctx) as Promise<TCanvas>\n }\n\n this.debug('cib is enabled, but not supports provided filter, fallback to manual math')\n }\n\n if (!this.capabilities.canvas && !this.capabilities.offscreen_canvas) {\n const err = new Error('Pica: cannot use getImageData on canvas, ' +\n \"make sure fingerprinting protection isn't enabled\")\n // @ts-ignore\n err.code = 'ERR_GET_IMAGE_DATA'\n throw err\n }\n\n //\n // No easy way, let's resize manually via arrays\n //\n\n return this.__planStagesAndResize(from, to, resizeParams, ctx) as Promise<TCanvas>\n }\n\n // RGBA buffer resize\n //\n async resizeBuffer (options: ResizeBufferOptions): Promise<Uint8Array> {\n const opts = Object.assign({}, DEFAULT_RESIZE_OPTS, options)\n\n // Legacy `.quality` option\n if (Object.prototype.hasOwnProperty.call(opts, 'quality')) {\n const quality = opts.quality\n if (typeof quality !== 'number' || quality < 0 || quality > 3) {\n throw new Error(`Pica: .quality should be [0..3], got ${quality}`)\n }\n opts.filter = utils.cib_quality_filter(quality)\n }\n\n await this.init()\n if (!this.__mathlib) throw new Error('Pica: math library is not initialized')\n\n const mathOpts: MathResizeAndUnsharpOptions = {\n src: opts.src,\n width: opts.width,\n height: opts.height,\n toWidth: opts.toWidth,\n toHeight: opts.toHeight,\n dest: opts.dest,\n scaleX: opts.toWidth / opts.width,\n scaleY: opts.toHeight / opts.height,\n offsetX: 0,\n offsetY: 0,\n filter: opts.filter,\n unsharpAmount: opts.unsharpAmount,\n unsharpRadius: opts.unsharpRadius,\n unsharpThreshold: opts.unsharpThreshold\n }\n\n return this.__mathlib.resizeAndUnsharp(mathOpts)\n }\n\n async toBlob (canvas: HTMLCanvasElement | OffscreenCanvas, mimeType?: string, quality?: number): Promise<Blob> {\n mimeType = mimeType || 'image/png'\n\n // Ordinary Canvas\n if ('toBlob' in canvas && canvas.toBlob) {\n return new Promise(resolve => {\n canvas.toBlob(blob => resolve(blob as Blob), mimeType, quality)\n })\n }\n\n // OffscreenCanvas\n if ('convertToBlob' in canvas && canvas.convertToBlob) {\n return canvas.convertToBlob({\n type: mimeType,\n quality\n })\n }\n\n // Fallback for old browsers\n const asString = atob((canvas as HTMLCanvasElement).toDataURL(mimeType, quality).split(',')[1])\n const len = asString.length\n const asBuffer = new Uint8Array(len)\n\n for (let i = 0; i < len; i++) {\n asBuffer[i] = asString.charCodeAt(i)\n }\n\n return new Blob([asBuffer], { type: mimeType })\n }\n\n debug (..._args: unknown[]): void {}\n}\n\nexport default function pica (options?: PicaOptions): Pica {\n return new Pica(options)\n}\n"],"x_google_ignoreList":[3],"mappings":"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"}
1
+ {"version":3,"file":"pica.min.mjs","names":[],"sources":["../../multimath/lib/base64decode.mjs","../../multimath/lib/wa_detect.mjs","../../multimath/lib/multimath.mjs","../node_modules/glur/lib/blur_mono16.mjs","../src/mm_unsharp_mask/unsharp_mask.ts","../src/mm_unsharp_mask/unsharp_mask_wasm.ts","../src/mm_unsharp_mask/unsharp_mask_wasm_base64.ts","../src/mm_unsharp_mask/index.ts","../src/mm_resize/resize_filter_info.ts","../src/mm_resize/resize_filter_gen.ts","../src/mm_resize/convolve.ts","../src/mm_resize/resize.ts","../src/mm_resize/resize_wasm.ts","../src/mm_resize/convolve_wasm_base64.ts","../src/mm_resize/index.ts","../src/mathlib.ts","../src/pool.ts","../src/utils.ts","../src/stepper.ts","../src/tiler.ts","../src/supported_features.ts","../src/pica_main.ts"],"sourcesContent":["// base64 decode str -> Uint8Array, to load WA modules\n//\nconst BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n\nexport default function base64decode (str) {\n const input = str.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length\n\n const out = new Uint8Array((max * 3) >> 2)\n\n // Collect by 6*4 bits (3 bytes)\n\n let bits = 0\n let ptr = 0\n\n for (let idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n out[ptr++] = (bits >> 16) & 0xFF\n out[ptr++] = (bits >> 8) & 0xFF\n out[ptr++] = bits & 0xFF\n }\n\n bits = (bits << 6) | BASE64_MAP.indexOf(input.charAt(idx))\n }\n\n // Dump tail\n\n const tailbits = (max % 4) * 6\n\n if (tailbits === 0) {\n out[ptr++] = (bits >> 16) & 0xFF\n out[ptr++] = (bits >> 8) & 0xFF\n out[ptr++] = bits & 0xFF\n } else if (tailbits === 18) {\n out[ptr++] = (bits >> 10) & 0xFF\n out[ptr++] = (bits >> 2) & 0xFF\n } else if (tailbits === 12) {\n out[ptr++] = (bits >> 4) & 0xFF\n }\n\n return out\n}\n","// Detect WebAssembly support.\n// - Check global WebAssembly object\n// - Try to load simple module (can be disabled via CSP)\n//\nlet wa\n\nexport default function hasWebAssembly () {\n // use cache if called before;\n if (typeof wa !== 'undefined') return wa\n\n wa = false\n\n if (typeof WebAssembly === 'undefined') return wa\n\n // If WebAssenbly is disabled, code can throw on compile\n try {\n // https://github.com/brion/min-wasm-fail/blob/master/min-wasm-fail.in.js\n // Additional check that WA internals are correct\n\n const bin = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 6, 1, 96, 1, 127, 1, 127, 3, 2, 1, 0, 5, 3, 1, 0, 1, 7, 8, 1, 4, 116, 101, 115, 116, 0, 0, 10, 16, 1, 14, 0, 32, 0, 65, 1, 54, 2, 0, 32, 0, 40, 2, 0, 11])\n const module = new WebAssembly.Module(bin)\n const instance = new WebAssembly.Instance(module, {})\n\n // test storing to and loading from a non-zero location via a parameter.\n // Safari on iOS 11.2.5 returns 0 unexpectedly at non-zero locations\n if (instance.exports.test(4) !== 0) wa = true\n\n return wa\n } catch (__) {}\n\n return wa\n}\n","import base64decode from './base64decode.mjs'\nimport hasWebAssembly from './wa_detect.mjs'\n\nconst DEFAULT_OPTIONS = {\n js: true,\n wasm: true\n}\n\nclass MultiMath {\n constructor (options) {\n const opts = Object.assign({}, DEFAULT_OPTIONS, options || {})\n\n this.options = opts\n\n this.__cache = {}\n\n this.__init_promise = null\n this.__modules = opts.modules || {}\n this.__memory = null\n this.__wasm = {}\n\n this.__isLE = ((new Uint32Array((new Uint8Array([1, 0, 0, 0])).buffer))[0] === 1)\n\n if (!this.options.js && !this.options.wasm) {\n throw new Error('mathlib: at least \"js\" or \"wasm\" should be enabled')\n }\n }\n\n has_wasm () { return hasWebAssembly() }\n\n use (module) {\n this.__modules[module.name] = module\n\n // Pin the best possible implementation\n if (this.options.wasm && this.has_wasm() && module.wasm_fn) {\n this[module.name] = module.wasm_fn\n } else {\n this[module.name] = module.fn\n }\n\n return this\n }\n\n init () {\n if (this.__init_promise) return this.__init_promise\n\n if (!this.options.js && this.options.wasm && !this.has_wasm()) {\n return Promise.reject(new Error('mathlib: only \"wasm\" was enabled, but it\\'s not supported'))\n }\n\n this.__init_promise = Promise.all(Object.keys(this.__modules).map(name => {\n const module = this.__modules[name]\n\n if (!this.options.wasm || !this.has_wasm() || !module.wasm_fn) return null\n\n // If already compiled - exit\n if (this.__wasm[name]) return null\n\n // Compile wasm source\n return WebAssembly.compile(base64decode(module.wasm_src))\n .then(m => { this.__wasm[name] = m })\n }))\n .then(() => this)\n\n return this.__init_promise\n }\n\n // //////////////////////////////////////////////////////////////////////////////\n // Methods below are for internal use from plugins\n\n // Increase current memory to include specified number of bytes. Do nothing if\n // size is already ok. You probably don't need to call this method directly,\n // because it will be invoked from `.__instance()`.\n //\n __reallocate (bytes) {\n if (!this.__memory) {\n this.__memory = new WebAssembly.Memory({\n initial: Math.ceil(bytes / (64 * 1024))\n })\n return this.__memory\n }\n\n const mem_size = this.__memory.buffer.byteLength\n\n if (mem_size < bytes) {\n this.__memory.grow(Math.ceil((bytes - mem_size) / (64 * 1024)))\n }\n\n return this.__memory\n }\n\n // Returns instantinated webassembly item by name, with specified memory size\n // and environment.\n // - use cache if available\n // - do sync module init, if async init was not called earlier\n // - allocate memory if not enougth\n // - can export functions to webassembly via \"env_extra\",\n // for example, { exp: Math.exp }\n //\n __instance (name, memsize, env_extra) {\n if (memsize) this.__reallocate(memsize)\n\n // If .init() was not called, do sync compile\n if (!this.__wasm[name]) {\n const module = this.__modules[name]\n this.__wasm[name] = new WebAssembly.Module(base64decode(module.wasm_src))\n }\n\n if (!this.__cache[name]) {\n const env_base = {\n memoryBase: 0,\n memory: this.__memory,\n tableBase: 0,\n table: new WebAssembly.Table({ initial: 0, element: 'anyfunc' })\n }\n\n this.__cache[name] = new WebAssembly.Instance(this.__wasm[name], {\n env: Object.assign(env_base, env_extra || {})\n })\n }\n\n return this.__cache[name]\n }\n\n // Helper to calculate memory aligh for pointers. Webassembly does not require\n // this, but you may wish to experiment. Default base = 8;\n //\n __align (number, base) {\n base = base || 8\n const reminder = number % base\n return number + (reminder ? base - reminder : 0)\n }\n}\n\nexport default MultiMath\n","// Calculate Gaussian blur of an image using IIR filter\n// The method is taken from Intel's white paper and code example attached to it:\n// https://software.intel.com/en-us/articles/iir-gaussian-blur-filter\n// -implementation-using-intel-advanced-vector-extensions\n\nfunction gaussCoef (sigma) {\n if (sigma < 0.5) {\n sigma = 0.5\n }\n\n const a = Math.exp(0.726 * 0.726) / sigma,\n g1 = Math.exp(-a),\n g2 = Math.exp(-2 * a),\n k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2)\n\n const a0 = k\n const a1 = k * (a - 1) * g1\n const a2 = k * (a + 1) * g1\n const a3 = -k * g2\n const b1 = 2 * g1\n const b2 = -g2\n const left_corner = (a0 + a1) / (1 - b1 - b2)\n const right_corner = (a2 + a3) / (1 - b1 - b2)\n\n // Attempt to force type to FP32.\n return new Float32Array([a0, a1, a2, a3, b1, b2, left_corner, right_corner])\n}\n\nfunction convolveMono16 (src, out, line, coeff, width, height) {\n // takes src image and writes the blurred and transposed result into out\n\n let prev_src, curr_src, curr_out, prev_out, prev_prev_out\n let src_index, out_index, line_index\n let i, j\n let coeff_a0, coeff_a1, coeff_b1, coeff_b2\n\n for (i = 0; i < height; i++) {\n src_index = i * width\n out_index = i\n line_index = 0\n\n // left to right\n prev_src = src[src_index]\n prev_prev_out = prev_src * coeff[6]\n prev_out = prev_prev_out\n\n coeff_a0 = coeff[0]\n coeff_a1 = coeff[1]\n coeff_b1 = coeff[4]\n coeff_b2 = coeff[5]\n\n for (j = 0; j < width; j++) {\n curr_src = src[src_index]\n\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2\n\n prev_prev_out = prev_out\n prev_out = curr_out\n prev_src = curr_src\n\n line[line_index] = prev_out\n line_index++\n src_index++\n }\n\n src_index--\n line_index--\n out_index += height * (width - 1)\n\n // right to left\n prev_src = src[src_index]\n prev_prev_out = prev_src * coeff[7]\n prev_out = prev_prev_out\n curr_src = prev_src\n\n coeff_a0 = coeff[2]\n coeff_a1 = coeff[3]\n\n for (j = width - 1; j >= 0; j--) {\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2\n\n prev_prev_out = prev_out\n prev_out = curr_out\n\n prev_src = curr_src\n curr_src = src[src_index]\n\n out[out_index] = line[line_index] + prev_out\n\n src_index--\n line_index--\n out_index -= height\n }\n }\n}\n\nfunction blurMono16 (src, width, height, radius) {\n // Quick exit on zero radius\n if (!radius) { return }\n\n const out = new Uint16Array(src.length),\n tmp_line = new Float32Array(Math.max(width, height))\n\n const coeff = gaussCoef(radius)\n\n convolveMono16(src, out, tmp_line, coeff, width, height, radius)\n convolveMono16(out, src, tmp_line, coeff, height, width, radius)\n}\n\nexport default blurMono16\n","// Unsharp mask filter\n//\n// http://stackoverflow.com/a/23322820/1031804\n// USM(O) = O + (2 * (Amount / 100) * (O - GB))\n// GB - gaussian blur.\n//\n// Image is converted from RGB to HSV, unsharp mask is applied to the\n// brightness channel and then image is converted back to RGB.\n//\nimport { blurMono16 } from 'glur'\nimport type { MathImageBuffer } from '../mathlib'\n\nfunction hsv_v16 (img: MathImageBuffer, width: number, height: number): Uint16Array {\n const size = width * height\n const out = new Uint16Array(size)\n let r, g, b, max\n for (let i = 0; i < size; i++) {\n r = img[4 * i]\n g = img[4 * i + 1]\n b = img[4 * i + 2]\n max = (r >= g && r >= b) ? r : (g >= b && g >= r) ? g : b\n out[i] = max << 8\n }\n return out\n}\n\nexport default function unsharp (\n img: MathImageBuffer,\n width: number,\n height: number,\n amount: number,\n radius: number,\n threshold: number\n): void {\n let v1, v2, vmul\n let diff, iTimes4\n\n if (amount === 0 || radius < 0.5) {\n return\n }\n if (radius > 2.0) {\n radius = 2.0\n }\n\n const brightness = hsv_v16(img, width, height)\n\n const blured = new Uint16Array(brightness) // copy, because blur modifies src\n\n blurMono16(blured, width, height, radius)\n\n const amountFp = (amount / 100 * 0x1000 + 0.5)|0\n const thresholdFp = threshold << 8\n\n const size = width * height\n\n for (let i = 0; i < size; i++) {\n v1 = brightness[i]\n diff = v1 - blured[i]\n\n if (Math.abs(diff) >= thresholdFp) {\n // add unsharp mask to the brightness channel\n v2 = v1 + ((amountFp * diff + 0x800) >> 12)\n\n // Both v1 and v2 are within [0.0 .. 255.0] (0000-FF00) range, never going into\n // [255.003 .. 255.996] (FF01-FFFF). This allows to round this value as (x+.5)|0\n // later without overflowing.\n v2 = v2 > 0xff00 ? 0xff00 : v2\n v2 = v2 < 0x0000 ? 0x0000 : v2\n\n // Avoid division by 0. V=0 means rgb(0,0,0), unsharp with unsharpAmount>0 cannot\n // change this value (because diff between colors gets inflated), so no need to verify correctness.\n v1 = v1 !== 0 ? v1 : 1\n\n // Multiplying V in HSV model by a constant is equivalent to multiplying each component\n // in RGB by the same constant (same for HSL), see also:\n // https://beesbuzz.biz/code/16-hsv-color-transforms\n vmul = ((v2 << 12) / v1)|0\n\n // Result will be in [0..255] range because:\n // - all numbers are positive\n // - r,g,b <= (v1/256)\n // - r,g,b,(v1/256),(v2/256) <= 255\n // So highest this number can get is X*255/X+0.5=255.5 which is < 256 and rounds down.\n\n iTimes4 = i * 4\n img[iTimes4] = (img[iTimes4] * vmul + 0x800) >> 12 // R\n img[iTimes4 + 1] = (img[iTimes4 + 1] * vmul + 0x800) >> 12 // G\n img[iTimes4 + 2] = (img[iTimes4 + 2] * vmul + 0x800) >> 12 // B\n }\n }\n}\n","import type { MathWasmContext, MathImageBuffer } from '../mathlib'\n\nexport default function unsharp (\n this: MathWasmContext,\n img: MathImageBuffer,\n width: number,\n height: number,\n amount: number,\n radius: number,\n threshold: number\n): void {\n if (amount === 0 || radius < 0.5) {\n return\n }\n\n if (radius > 2.0) {\n radius = 2.0\n }\n\n const pixels = width * height\n\n const img_bytes_cnt = pixels * 4\n const hsv_bytes_cnt = pixels * 2\n const blur_bytes_cnt = pixels * 2\n const blur_line_byte_cnt = Math.max(width, height) * 4 // float32 array\n const blur_coeffs_byte_cnt = 8 * 4 // float32 array\n\n const img_offset = 0\n const hsv_offset = img_bytes_cnt\n const blur_offset = hsv_offset + hsv_bytes_cnt\n const blur_tmp_offset = blur_offset + blur_bytes_cnt\n const blur_line_offset = blur_tmp_offset + blur_bytes_cnt\n const blur_coeffs_offset = blur_line_offset + blur_line_byte_cnt\n\n const instance = this.__instance(\n 'unsharp_mask',\n img_bytes_cnt + hsv_bytes_cnt + blur_bytes_cnt * 2 + blur_line_byte_cnt + blur_coeffs_byte_cnt,\n { exp: Math.exp }\n )\n\n // 32-bit copy is much faster in chrome\n const img32 = new Uint32Array(img.buffer)\n const mem32 = new Uint32Array(this.__memory!.buffer)\n mem32.set(img32)\n\n // HSL\n let fn = (instance.exports.hsv_v16 || instance.exports._hsv_v16) as Function | undefined\n if (!fn) throw new Error('WASM hsv_v16 function is not available')\n fn(img_offset, hsv_offset, width, height)\n\n // BLUR\n fn = (instance.exports.blurMono16 || instance.exports._blurMono16) as Function | undefined\n if (!fn) throw new Error('WASM blurMono16 function is not available')\n fn(hsv_offset, blur_offset, blur_tmp_offset,\n blur_line_offset, blur_coeffs_offset, width, height, radius)\n\n // UNSHARP\n fn = (instance.exports.unsharp || instance.exports._unsharp) as Function | undefined\n if (!fn) throw new Error('WASM unsharp function is not available')\n fn(img_offset, img_offset, hsv_offset,\n blur_offset, width, height, amount, threshold)\n\n // 32-bit copy is much faster in chrome\n img32.set(new Uint32Array(this.__memory!.buffer, 0, pixels))\n}\n","// This is autogenerated file from math.wasm, don't edit.\n//\nexport default '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'\n","import fn from './unsharp_mask'\nimport wasm_fn from './unsharp_mask_wasm'\nimport wasm_src from './unsharp_mask_wasm_base64'\n\nexport default {\n name: 'unsharp_mask' as const,\n fn,\n wasm_fn,\n wasm_src\n}\n","import type { MathResizeFilter } from '../mathlib'\n\n// Filter definitions to build tables for\n// resizing convolvers.\n//\n// Presets for quality 0..3. Filter functions + window size\n//\nexport interface FilterInfo {\n win: number\n fn: (x: number) => number\n}\n\nconst filter: Record<MathResizeFilter, FilterInfo> = {\n // Nearest neighbor\n box: {\n win: 0.5,\n fn (x: number) {\n if (x < 0) x = -x\n return (x < 0.5) ? 1.0 : 0.0\n }\n },\n // // Hamming\n hamming: {\n win: 1.0,\n fn (x: number) {\n if (x < 0) x = -x\n if (x >= 1.0) { return 0.0 }\n if (x < 1.19209290E-07) { return 1.0 }\n const xpi = x * Math.PI\n return ((Math.sin(xpi) / xpi) * (0.54 + 0.46 * Math.cos(xpi / 1.0)))\n }\n },\n // Lanczos, win = 2\n lanczos2: {\n win: 2.0,\n fn (x: number) {\n if (x < 0) x = -x\n if (x >= 2.0) { return 0.0 }\n if (x < 1.19209290E-07) { return 1.0 }\n const xpi = x * Math.PI\n return (Math.sin(xpi) / xpi) * Math.sin(xpi / 2.0) / (xpi / 2.0)\n }\n },\n // Lanczos, win = 3\n lanczos3: {\n win: 3.0,\n fn (x: number) {\n if (x < 0) x = -x\n if (x >= 3.0) { return 0.0 }\n if (x < 1.19209290E-07) { return 1.0 }\n const xpi = x * Math.PI\n return (Math.sin(xpi) / xpi) * Math.sin(xpi / 3.0) / (xpi / 3.0)\n }\n },\n // Magic Kernel Sharp 2013, win = 2.5\n // http://johncostella.com/magic/\n mks2013: {\n win: 2.5,\n fn (x: number) {\n if (x < 0) x = -x\n if (x >= 2.5) { return 0.0 }\n if (x >= 1.5) { return -0.125 * (x - 2.5) * (x - 2.5) }\n if (x >= 0.5) { return 0.25 * (4 * x * x - 11 * x + 7) }\n return 1.0625 - 1.75 * x * x\n }\n }\n}\n\nexport default {\n filter\n}\n","// Calculate convolution filters for each destination point,\n// and pack data to Int16Array:\n//\n// [ shift, length, data..., shift2, length2, data..., ... ]\n//\n// - shift - offset in src image\n// - length - filter length (in src points)\n// - data - filter values sequence\n//\nimport FILTER_INFO from './resize_filter_info'\nimport type { MathResizeFilter } from '../mathlib'\n\n// Precision of fixed FP values\nconst FIXED_FRAC_BITS = 14\n\nfunction toFixedPoint (num: number): number {\n return Math.round(num * ((1 << FIXED_FRAC_BITS) - 1))\n}\n\nexport default function resizeFilterGen (\n filter: MathResizeFilter,\n srcSize: number,\n destSize: number,\n scale: number,\n offset: number\n): Int16Array {\n const filterFunction = FILTER_INFO.filter[filter].fn\n\n const scaleInverted = 1.0 / scale\n const scaleClamped = Math.min(1.0, scale) // For upscale\n\n // Filter window (averaging interval), scaled to src image\n const srcWindow = FILTER_INFO.filter[filter].win / scaleClamped\n\n let destPixel, srcPixel, srcFirst, srcLast, filterElementSize,\n floatFilter, fxpFilter, total, pxl, idx, floatVal, filterTotal, filterVal\n let leftNotEmpty, rightNotEmpty, filterShift, filterSize\n\n const maxFilterElementSize = Math.floor((srcWindow + 1) * 2)\n const packedFilter = new Int16Array((maxFilterElementSize + 2) * destSize)\n let packedFilterPtr = 0\n\n const slowCopy = !packedFilter.subarray || !packedFilter.set\n\n // For each destination pixel calculate source range and built filter values\n for (destPixel = 0; destPixel < destSize; destPixel++) {\n // Scaling should be done relative to central pixel point\n srcPixel = (destPixel + 0.5) * scaleInverted + offset\n\n srcFirst = Math.max(0, Math.floor(srcPixel - srcWindow))\n srcLast = Math.min(srcSize - 1, Math.ceil(srcPixel + srcWindow))\n\n filterElementSize = srcLast - srcFirst + 1\n floatFilter = new Float32Array(filterElementSize)\n fxpFilter = new Int16Array(filterElementSize)\n\n total = 0.0\n\n // Fill filter values for calculated range\n for (pxl = srcFirst, idx = 0; pxl <= srcLast; pxl++, idx++) {\n floatVal = filterFunction(((pxl + 0.5) - srcPixel) * scaleClamped)\n total += floatVal\n floatFilter[idx] = floatVal\n }\n\n // Normalize filter, convert to fixed point and accumulate conversion error\n filterTotal = 0\n\n for (idx = 0; idx < floatFilter.length; idx++) {\n filterVal = floatFilter[idx] / total\n filterTotal += filterVal\n fxpFilter[idx] = toFixedPoint(filterVal)\n }\n\n // Compensate normalization error, to minimize brightness drift\n fxpFilter[destSize >> 1] += toFixedPoint(1.0 - filterTotal)\n\n //\n // Now pack filter to useable form\n //\n // 1. Trim leading and trailing zero values, and compensate shift/length\n // 2. Put all to single array in this format:\n //\n // [ pos shift, data length, value1, value2, value3, ... ]\n //\n\n leftNotEmpty = 0\n while (leftNotEmpty < fxpFilter.length && fxpFilter[leftNotEmpty] === 0) {\n leftNotEmpty++\n }\n\n if (leftNotEmpty < fxpFilter.length) {\n rightNotEmpty = fxpFilter.length - 1\n while (rightNotEmpty > 0 && fxpFilter[rightNotEmpty] === 0) {\n rightNotEmpty--\n }\n\n filterShift = srcFirst + leftNotEmpty\n filterSize = rightNotEmpty - leftNotEmpty + 1\n\n packedFilter[packedFilterPtr++] = filterShift // shift\n packedFilter[packedFilterPtr++] = filterSize // size\n\n if (!slowCopy) {\n packedFilter.set(fxpFilter.subarray(leftNotEmpty, rightNotEmpty + 1), packedFilterPtr)\n packedFilterPtr += filterSize\n } else {\n // fallback for old IE < 11, without subarray/set methods\n for (idx = leftNotEmpty; idx <= rightNotEmpty; idx++) {\n packedFilter[packedFilterPtr++] = fxpFilter[idx]\n }\n }\n } else {\n // zero data, write header only\n packedFilter[packedFilterPtr++] = 0 // shift\n packedFilter[packedFilterPtr++] = 0 // size\n }\n }\n return packedFilter\n}\n","// Resize convolvers, pure JS implementation\n//\n// Precision of fixed FP values\n// var FIXED_FRAC_BITS = 14;\n\nfunction clampTo8 (i: number): number { return i < 0 ? 0 : (i > 255 ? 255 : i) }\nfunction clampNegative (i: number): number { return i >= 0 ? i : 0 }\n\nimport type { MathImageBuffer } from '../mathlib'\n\n// Convolve image data in horizontal direction. Can be used for:\n//\n// 1. bitmap with premultiplied alpha\n// 2. bitmap without alpha (all values 255)\n//\n// Notes:\n//\n// - output is transposed\n// - output resolution is ~15 bits per channel(for better precision).\n//\nfunction convolveHor (\n src: MathImageBuffer,\n dest: Uint16Array,\n srcW: number,\n srcH: number,\n destW: number,\n filters: Int16Array\n): void {\n let r, g, b, a\n let filterPtr, filterShift, filterSize\n let srcPtr, srcY, destX, filterVal\n let srcOffset = 0, destOffset = 0\n\n // For each row\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0\n\n // Apply precomputed filters to each destination row point\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++]\n filterSize = filters[filterPtr++]\n\n srcPtr = (srcOffset + (filterShift * 4))|0\n\n r = g = b = a = 0\n\n // Apply the filter to the row to get the destination pixel r, g, b, a\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]\n\n // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n a = (a + filterVal * src[srcPtr + 3])|0\n b = (b + filterVal * src[srcPtr + 2])|0\n g = (g + filterVal * src[srcPtr + 1])|0\n r = (r + filterVal * src[srcPtr])|0\n srcPtr = (srcPtr + 4)|0\n }\n\n // Store 15 bits between passes for better precision\n // Instead of shift to 14 (FIXED_FRAC_BITS), shift to 7 only\n //\n dest[destOffset + 3] = clampNegative(a >> 7)\n dest[destOffset + 2] = clampNegative(b >> 7)\n dest[destOffset + 1] = clampNegative(g >> 7)\n dest[destOffset] = clampNegative(r >> 7)\n destOffset = (destOffset + srcH * 4)|0\n }\n\n destOffset = ((srcY + 1) * 4)|0\n srcOffset = ((srcY + 1) * srcW * 4)|0\n }\n}\n\n// Supplementary method for `convolveHor()`\n//\nfunction convolveVert (\n src: Uint16Array,\n dest: Uint8Array,\n srcW: number,\n srcH: number,\n destW: number,\n filters: Int16Array\n): void {\n let r, g, b, a\n let filterPtr, filterShift, filterSize\n let srcPtr, srcY, destX, filterVal\n let srcOffset = 0, destOffset = 0\n\n // For each row\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0\n\n // Apply precomputed filters to each destination row point\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++]\n filterSize = filters[filterPtr++]\n\n srcPtr = (srcOffset + (filterShift * 4))|0\n\n r = g = b = a = 0\n\n // Apply the filter to the row to get the destination pixel r, g, b, a\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]\n\n // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n a = (a + filterVal * src[srcPtr + 3])|0\n b = (b + filterVal * src[srcPtr + 2])|0\n g = (g + filterVal * src[srcPtr + 1])|0\n r = (r + filterVal * src[srcPtr])|0\n srcPtr = (srcPtr + 4)|0\n }\n\n // Sync with premultiplied version for exact result match\n r >>= 7\n g >>= 7\n b >>= 7\n a >>= 7\n\n // Bring this value back in range + round result.\n //\n dest[destOffset + 3] = clampTo8((a + (1 << 13)) >> 14)\n dest[destOffset + 2] = clampTo8((b + (1 << 13)) >> 14)\n dest[destOffset + 1] = clampTo8((g + (1 << 13)) >> 14)\n dest[destOffset] = clampTo8((r + (1 << 13)) >> 14)\n destOffset = (destOffset + srcH * 4)|0\n }\n\n destOffset = ((srcY + 1) * 4)|0\n srcOffset = ((srcY + 1) * srcW * 4)|0\n }\n}\n\n// Premultiply & convolve image data in horizontal direction. Can be used for:\n//\n// - Any bitmap data, extracted with `.getImageData()` method (with\n// non-premultiplied alpha)\n//\n// For images without alpha channel this method is slower than `convolveHor()`\n//\nfunction convolveHorWithPre (\n src: MathImageBuffer,\n dest: Uint16Array,\n srcW: number,\n srcH: number,\n destW: number,\n filters: Int16Array\n): void {\n let r, g, b, a, alpha\n let filterPtr, filterShift, filterSize\n let srcPtr, srcY, destX, filterVal\n let srcOffset = 0, destOffset = 0\n\n // For each row\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0\n\n // Apply precomputed filters to each destination row point\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++]\n filterSize = filters[filterPtr++]\n\n srcPtr = (srcOffset + (filterShift * 4))|0\n\n r = g = b = a = 0\n\n // Apply the filter to the row to get the destination pixel r, g, b, a\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]\n\n // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n alpha = src[srcPtr + 3]\n a = (a + filterVal * alpha)|0\n b = (b + filterVal * src[srcPtr + 2] * alpha)|0\n g = (g + filterVal * src[srcPtr + 1] * alpha)|0\n r = (r + filterVal * src[srcPtr] * alpha)|0\n srcPtr = (srcPtr + 4)|0\n }\n\n // Premultiply is (* alpha / 255).\n // Postpone division for better performance\n b = (b / 255)|0\n g = (g / 255)|0\n r = (r / 255)|0\n\n // Store 15 bits between passes for better precision\n // Instead of shift to 14 (FIXED_FRAC_BITS), shift to 7 only\n //\n dest[destOffset + 3] = clampNegative(a >> 7)\n dest[destOffset + 2] = clampNegative(b >> 7)\n dest[destOffset + 1] = clampNegative(g >> 7)\n dest[destOffset] = clampNegative(r >> 7)\n destOffset = (destOffset + srcH * 4)|0\n }\n\n destOffset = ((srcY + 1) * 4)|0\n srcOffset = ((srcY + 1) * srcW * 4)|0\n }\n}\n\n// Supplementary method for `convolveHorWithPre()`\n//\nfunction convolveVertWithPre (\n src: Uint16Array,\n dest: Uint8Array,\n srcW: number,\n srcH: number,\n destW: number,\n filters: Int16Array\n): void {\n let r, g, b, a\n let filterPtr, filterShift, filterSize\n let srcPtr, srcY, destX, filterVal\n let srcOffset = 0, destOffset = 0\n\n // For each row\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0\n\n // Apply precomputed filters to each destination row point\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++]\n filterSize = filters[filterPtr++]\n\n srcPtr = (srcOffset + (filterShift * 4))|0\n\n r = g = b = a = 0\n\n // Apply the filter to the row to get the destination pixel r, g, b, a\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]\n\n // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n a = (a + filterVal * src[srcPtr + 3])|0\n b = (b + filterVal * src[srcPtr + 2])|0\n g = (g + filterVal * src[srcPtr + 1])|0\n r = (r + filterVal * src[srcPtr])|0\n srcPtr = (srcPtr + 4)|0\n }\n\n // Downscale to leave room for un-premultiply\n r >>= 7\n g >>= 7\n b >>= 7\n a >>= 7\n\n // Un-premultiply\n a = clampTo8((a + (1 << 13)) >> 14)\n if (a > 0) {\n r = (r * 255 / a)|0\n g = (g * 255 / a)|0\n b = (b * 255 / a)|0\n }\n\n // Bring this value back in range + round result.\n // Shift value = FIXED_FRAC_BITS + 7\n //\n dest[destOffset + 3] = a\n dest[destOffset + 2] = clampTo8((b + (1 << 13)) >> 14)\n dest[destOffset + 1] = clampTo8((g + (1 << 13)) >> 14)\n dest[destOffset] = clampTo8((r + (1 << 13)) >> 14)\n destOffset = (destOffset + srcH * 4)|0\n }\n\n destOffset = ((srcY + 1) * 4)|0\n srcOffset = ((srcY + 1) * srcW * 4)|0\n }\n}\n\nexport {\n convolveHor,\n convolveVert,\n convolveHorWithPre,\n convolveVertWithPre\n}\n","import createFilters from './resize_filter_gen'\nimport { convolveHor, convolveVert, convolveHorWithPre, convolveVertWithPre } from './convolve'\nimport type { MathResizeOptions, MathImageBuffer } from '../mathlib'\n\nfunction hasAlpha (src: MathImageBuffer, width: number, height: number): boolean {\n let ptr = 3\n const len = (width * height * 4)|0\n while (ptr < len) {\n if (src[ptr] !== 255) return true\n ptr = (ptr + 4)|0\n }\n return false\n}\n\nfunction resetAlpha (dst: Uint8Array, width: number, height: number): void {\n let ptr = 3\n const len = (width * height * 4)|0\n while (ptr < len) { dst[ptr] = 0xFF; ptr = (ptr + 4)|0 }\n}\n\nexport default function resize (options: MathResizeOptions): Uint8Array {\n const src = options.src\n const srcW = options.width\n const srcH = options.height\n const destW = options.toWidth\n const destH = options.toHeight\n const scaleX = options.scaleX || options.toWidth / options.width\n const scaleY = options.scaleY || options.toHeight / options.height\n const offsetX = options.offsetX || 0\n const offsetY = options.offsetY || 0\n const dest = options.dest || new Uint8Array(destW * destH * 4)\n\n const filter = typeof options.filter === 'undefined' ? 'mks2013' : options.filter\n const filtersX = createFilters(filter, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(filter, srcH, destH, scaleY, offsetY)\n\n const tmp = new Uint16Array(destW * srcH * 4)\n\n // Autodetect if alpha channel exists, and use appropriate method\n if (hasAlpha(src, srcW, srcH)) {\n convolveHorWithPre(src, tmp, srcW, srcH, destW, filtersX)\n convolveVertWithPre(tmp, dest, srcH, destW, destH, filtersY)\n } else {\n convolveHor(src, tmp, srcW, srcH, destW, filtersX)\n convolveVert(tmp, dest, srcH, destW, destH, filtersY)\n resetAlpha(dest, destW, destH)\n }\n\n return dest\n}\n","import createFilters from './resize_filter_gen'\nimport type { MathResizeOptions, MathWasmContext, MathImageBuffer } from '../mathlib'\n\nfunction hasAlpha (src: MathImageBuffer, width: number, height: number): boolean {\n let ptr = 3\n const len = (width * height * 4)|0\n while (ptr < len) {\n if (src[ptr] !== 255) return true\n ptr = (ptr + 4)|0\n }\n return false\n}\n\nfunction resetAlpha (dst: Uint8Array, width: number, height: number): void {\n let ptr = 3\n const len = (width * height * 4)|0\n while (ptr < len) { dst[ptr] = 0xFF; ptr = (ptr + 4)|0 }\n}\n\nfunction asUint8Array (src: Int16Array): Uint8Array {\n return new Uint8Array(src.buffer, 0, src.byteLength)\n}\n\nlet IS_LE = true\n// should not crash everything on module load in old browsers\ntry {\n IS_LE = ((new Uint32Array((new Uint8Array([1, 0, 0, 0])).buffer))[0] === 1)\n} catch (__) {}\n\nfunction copyInt16asLE (src: Int16Array, target: Uint8Array, target_offset: number): void {\n if (IS_LE) {\n target.set(asUint8Array(src), target_offset)\n return\n }\n\n for (let ptr = target_offset, i = 0; i < src.length; i++) {\n const data = src[i]\n target[ptr++] = data & 0xFF\n target[ptr++] = (data >> 8) & 0xFF\n }\n}\n\nexport default function resize_wasm (this: MathWasmContext, options: MathResizeOptions): Uint8Array {\n const src = options.src\n const srcW = options.width\n const srcH = options.height\n const destW = options.toWidth\n const destH = options.toHeight\n const scaleX = options.scaleX || options.toWidth / options.width\n const scaleY = options.scaleY || options.toHeight / options.height\n const offsetX = options.offsetX || 0.0\n const offsetY = options.offsetY || 0.0\n const dest = options.dest || new Uint8Array(destW * destH * 4)\n\n const filter = typeof options.filter === 'undefined' ? 'mks2013' : options.filter\n const filtersX = createFilters(filter, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(filter, srcH, destH, scaleY, offsetY)\n\n // destination is 0 too.\n const src_offset = 0\n const src_size = Math.max(src.byteLength, dest.byteLength)\n // buffer between convolve passes\n const tmp_offset = this.__align(src_offset + src_size)\n const tmp_size = srcH * destW * 4 * 2 // 2 bytes per channel\n\n const filtersX_offset = this.__align(tmp_offset + tmp_size)\n const filtersY_offset = this.__align(filtersX_offset + filtersX.byteLength)\n const alloc_bytes = filtersY_offset + filtersY.byteLength\n\n const instance = this.__instance('resize', alloc_bytes)\n\n //\n // Fill memory block with data to process\n //\n\n const mem = new Uint8Array(this.__memory!.buffer)\n const mem32 = new Uint32Array(this.__memory!.buffer)\n\n // 32-bit copy is much faster in chrome\n const src32 = new Uint32Array(src.buffer)\n mem32.set(src32)\n\n // We should guarantee LE bytes order. Filters are not big, so\n // speed difference is not significant vs direct .set()\n copyInt16asLE(filtersX, mem, filtersX_offset)\n copyInt16asLE(filtersY, mem, filtersY_offset)\n\n // Now call webassembly method\n // emsdk does method names with '_'\n const fn = (instance.exports.convolveHV || instance.exports._convolveHV) as Function | undefined\n if (!fn) throw new Error('WASM resize function is not available')\n\n if (hasAlpha(src, srcW, srcH)) {\n fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH, 1)\n } else {\n fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH, 0)\n resetAlpha(dest, destW, destH)\n }\n\n //\n // Copy data back to typed array\n //\n\n // 32-bit copy is much faster in chrome\n const dest32 = new Uint32Array(dest.buffer)\n dest32.set(new Uint32Array(this.__memory!.buffer, 0, destH * destW))\n\n return dest\n}\n","// This is autogenerated file from math.wasm, don't edit.\n//\nexport default 'AGFzbQEAAAAADAZkeWxpbmsAAAAAAAEYA2AGf39/f39/AGAAAGAIf39/f39/f38AAg8BA2VudgZtZW1vcnkCAAADBwYBAAAAAAIGBgF/AEEACweUAQgRX193YXNtX2NhbGxfY3RvcnMAAAtjb252b2x2ZUhvcgABDGNvbnZvbHZlVmVydAACEmNvbnZvbHZlSG9yV2l0aFByZQADE2NvbnZvbHZlVmVydFdpdGhQcmUABApjb252b2x2ZUhWAAUMX19kc29faGFuZGxlAwAYX193YXNtX2FwcGx5X2RhdGFfcmVsb2NzAAAKyA4GAwABC4wDARB/AkAgA0UNACAERQ0AIANBAnQhFQNAQQAhE0EAIQsDQCALQQJqIQcCfyALQQF0IAVqIgYuAQIiC0UEQEEAIQhBACEGQQAhCUEAIQogBwwBCyASIAYuAQBqIQhBACEJQQAhCiALIRRBACEOIAchBkEAIQ8DQCAFIAZBAXRqLgEAIhAgACAIQQJ0aigCACIRQRh2bCAPaiEPIBFB/wFxIBBsIAlqIQkgEUEQdkH/AXEgEGwgDmohDiARQQh2Qf8BcSAQbCAKaiEKIAhBAWohCCAGQQFqIQYgFEEBayIUDQALIAlBB3UhCCAKQQd1IQYgDkEHdSEJIA9BB3UhCiAHIAtqCyELIAEgDEEBdCIHaiAIQQAgCEEAShs7AQAgASAHQQJyaiAGQQAgBkEAShs7AQAgASAHQQRyaiAJQQAgCUEAShs7AQAgASAHQQZyaiAKQQAgCkEAShs7AQAgDCAVaiEMIBNBAWoiEyAERw0ACyANQQFqIg0gAmwhEiANQQJ0IQwgAyANRw0ACwsL2gMBD38CQCADRQ0AIARFDQAgAkECdCEUA0AgCyEMQQAhE0EAIQIDQCACQQJqIQYCfyACQQF0IAVqIgcuAQIiAkUEQEEAIQhBACEHQQAhCkEAIQkgBgwBCyAHLgEAQQJ0IBJqIQhBACEJIAIhCkEAIQ0gBiEHQQAhDkEAIQ8DQCAFIAdBAXRqLgEAIhAgACAIQQF0IhFqLwEAbCAJaiEJIAAgEUEGcmovAQAgEGwgDmohDiAAIBFBBHJqLwEAIBBsIA9qIQ8gACARQQJyai8BACAQbCANaiENIAhBBGohCCAHQQFqIQcgCkEBayIKDQALIAlBB3UhCCANQQd1IQcgDkEHdSEKIA9BB3UhCSACIAZqCyECIAEgDEECdGogB0GAQGtBDnUiBkH/ASAGQf8BSBsiBkEAIAZBAEobQQh0QYD+A3EgCUGAQGtBDnUiBkH/ASAGQf8BSBsiBkEAIAZBAEobQRB0QYCA/AdxIApBgEBrQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG0EYdHJyIAhBgEBrQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG3I2AgAgAyAMaiEMIBNBAWoiEyAERw0ACyAUIAtBAWoiC2whEiADIAtHDQALCwuSAwEQfwJAIANFDQAgBEUNACADQQJ0IRUDQEEAIRNBACEGA0AgBkECaiEIAn8gBkEBdCAFaiIGLgECIgdFBEBBACEJQQAhDEEAIQ1BACEOIAgMAQsgEiAGLgEAaiEJQQAhDkEAIQ1BACEMIAchFEEAIQ8gCCEGA0AgBSAGQQF0ai4BACAAIAlBAnRqKAIAIhBBGHZsIhEgD2ohDyARIBBBEHZB/wFxbCAMaiEMIBEgEEEIdkH/AXFsIA1qIQ0gESAQQf8BcWwgDmohDiAJQQFqIQkgBkEBaiEGIBRBAWsiFA0ACyAPQQd1IQkgByAIagshBiABIApBAXQiCGogDkH/AW1BB3UiB0EAIAdBAEobOwEAIAEgCEECcmogDUH/AW1BB3UiB0EAIAdBAEobOwEAIAEgCEEEcmogDEH/AW1BB3UiB0EAIAdBAEobOwEAIAEgCEEGcmogCUEAIAlBAEobOwEAIAogFWohCiATQQFqIhMgBEcNAAsgC0EBaiILIAJsIRIgC0ECdCEKIAMgC0cNAAsLC4IEAQ9/AkAgA0UNACAERQ0AIAJBAnQhFANAIAshDEEAIRJBACEHA0AgB0ECaiEKAn8gB0EBdCAFaiICLgECIhNFBEBBACEIQQAhCUEAIQYgCiEHQQAMAQsgAi4BAEECdCARaiEJQQAhByATIQJBACENIAohBkEAIQ5BACEPA0AgBSAGQQF0ai4BACIIIAAgCUEBdCIQai8BAGwgB2ohByAAIBBBBnJqLwEAIAhsIA5qIQ4gACAQQQRyai8BACAIbCAPaiEPIAAgEEECcmovAQAgCGwgDWohDSAJQQRqIQkgBkEBaiEGIAJBAWsiAg0ACyAHQQd1IQggDUEHdSEJIA9BB3UhBiAKIBNqIQcgDkEHdQtBgEBrQQ51IgJB/wEgAkH/AUgbIgJBACACQQBKGyIKQf8BcQRAIAlB/wFsIAJtIQkgCEH/AWwgAm0hCCAGQf8BbCACbSEGCyABIAxBAnRqIAlBgEBrQQ51IgJB/wEgAkH/AUgbIgJBACACQQBKG0EIdEGA/gNxIAZBgEBrQQ51IgJB/wEgAkH/AUgbIgJBACACQQBKG0EQdEGAgPwHcSAKQRh0ciAIQYBAa0EOdSICQf8BIAJB/wFIGyICQQAgAkEAShtycjYCACADIAxqIQwgEkEBaiISIARHDQALIBQgC0EBaiILbCERIAMgC0cNAAsLC0AAIAcEQEEAIAIgAyAEIAUgABADIAJBACAEIAUgBiABEAQPC0EAIAIgAyAEIAUgABABIAJBACAEIAUgBiABEAIL'\n","import fn from './resize'\nimport wasm_fn from './resize_wasm'\nimport wasm_src from './convolve_wasm_base64'\n\nexport default {\n name: 'resize' as const,\n fn,\n wasm_fn,\n wasm_src\n}\n","// Collection of math functions\n//\n// 1. Combine components together\n// 2. Has async init to load wasm modules\n//\nimport { MultiMath } from 'multimath'\n\nimport mm_unsharp_mask from './mm_unsharp_mask'\nimport mm_resize from './mm_resize'\n\nexport type MathFeaturesMap = { js: boolean; wasm: boolean }\nexport type { MultiMathPlugin as MathPlugin } from 'multimath'\nexport type MathImageBuffer = Uint8Array | Uint8ClampedArray\nexport type MathWasmContext = MultiMath\n\nexport type MathResizeFilter = 'box' | 'hamming' | 'lanczos2' | 'lanczos3' | 'mks2013'\n\nexport interface MathResizeOptions {\n src: MathImageBuffer\n width: number\n height: number\n toWidth: number\n toHeight: number\n dest?: Uint8Array\n scaleX: number\n scaleY: number\n offsetX: number\n offsetY: number\n filter: MathResizeFilter\n}\n\nexport interface MathResizeAndUnsharpOptions extends MathResizeOptions {\n unsharpAmount: number\n unsharpRadius: number\n unsharpThreshold: number\n}\n\nexport default class MathLib extends MultiMath {\n declare features: MathFeaturesMap\n declare resize: typeof mm_resize.fn\n declare unsharp_mask: typeof mm_unsharp_mask.fn\n\n constructor (requested_features?: readonly string[]) {\n const __requested_features = requested_features || []\n\n const features = {\n js: __requested_features.indexOf('js') >= 0,\n wasm: __requested_features.indexOf('wasm') >= 0\n }\n\n super(features)\n\n this.features = {\n js: features.js,\n wasm: features.wasm && this.has_wasm()\n }\n\n this.use(mm_unsharp_mask)\n this.use(mm_resize)\n }\n\n resizeAndUnsharp (options: MathResizeAndUnsharpOptions): Uint8Array {\n const result = this.resize(options)\n\n if (options.unsharpAmount) {\n this.unsharp_mask(\n result,\n options.toWidth,\n options.toHeight,\n options.unsharpAmount,\n options.unsharpRadius,\n options.unsharpThreshold\n )\n }\n\n return result\n }\n}\n","const GC_INTERVAL = 100\n\n// Acquired items\nexport interface PoolResource<T> {\n value: T\n release: () => void\n}\n\n// Internal storage format\ninterface PoolResourceDescriptor<T> {\n id: number\n lastUsed: number\n value: T\n destroy: () => void\n}\n\nexport default class Pool<T> {\n create: () => { value: T, destroy: () => void }\n available: Array<PoolResourceDescriptor<T>>\n acquired: Record<number, PoolResourceDescriptor<T>>\n lastId: number\n timeoutId: ReturnType<typeof setTimeout> | 0\n idle: number\n\n constructor (create: () => { value: T, destroy: () => void }, idle?: number) {\n this.create = create\n\n this.available = []\n this.acquired = {}\n this.lastId = 1\n\n this.timeoutId = 0\n this.idle = idle || 2000\n }\n\n acquire (): PoolResource<T> {\n let descriptor: PoolResourceDescriptor<T>\n\n if (this.available.length !== 0) {\n descriptor = this.available.pop() as PoolResourceDescriptor<T>\n } else {\n const init = this.create()\n descriptor = { ...init, id: this.lastId++, lastUsed: 0 }\n }\n this.acquired[descriptor.id] = descriptor\n return { value: descriptor.value, release: () => this.release(descriptor) }\n }\n\n release (descriptor: PoolResourceDescriptor<T>): void {\n delete this.acquired[descriptor.id]\n\n descriptor.lastUsed = Date.now()\n this.available.push(descriptor)\n\n if (this.timeoutId === 0) {\n this.timeoutId = setTimeout(() => this.gc(), GC_INTERVAL)\n }\n }\n\n gc (): void {\n const now = Date.now()\n\n this.available = this.available.filter(descriptor => {\n if (now - descriptor.lastUsed > this.idle) {\n descriptor.destroy()\n return false\n }\n return true\n })\n\n if (this.available.length !== 0) {\n this.timeoutId = setTimeout(() => this.gc(), GC_INTERVAL)\n } else {\n this.timeoutId = 0\n }\n }\n}\n","import type { CibResizeQuality, Filter, Limiter, PicaCanvas } from './types'\n\n// Uses constructor.name — safe because all targets are browser built-ins or\n// native Node.js library classes that minifiers don't rename. If this ever\n// breaks after a toolchain change, fall back to Object.prototype.toString:\n// Object.prototype.toString.call(obj) === '[object HTMLCanvasElement]' etc.\nfunction objClass (obj: unknown): string {\n return (obj as any)?.constructor?.name ?? ''\n}\n\nexport function isCanvas (element: unknown): element is PicaCanvas {\n const cname = objClass(element)\n\n return cname === 'HTMLCanvasElement' ||\n cname === 'OffscreenCanvas' ||\n cname === 'Canvas' /* node-canvas */ ||\n cname === 'CanvasElement' /* @napi-rs/canvas */\n}\n\nexport function isImage (element: unknown): element is HTMLImageElement {\n return objClass(element) === 'HTMLImageElement'\n}\n\nexport function isImageBitmap (element: unknown): element is ImageBitmap {\n return objClass(element) === 'ImageBitmap'\n}\n\nexport function limiter (concurrency: number): Limiter {\n let active = 0\n const queue: Array<() => void> = []\n\n function roll () {\n if (active < concurrency && queue.length) {\n active++\n queue.shift()?.()\n }\n }\n\n return function limit<T> (fn: () => Promise<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n queue.push(() => {\n fn().then(\n result => {\n resolve(result)\n active--\n roll()\n },\n err => {\n reject(err)\n active--\n roll()\n }\n )\n })\n\n roll()\n })\n }\n}\n\nexport function cib_quality_name (num: number): ResizeQuality {\n switch (num) {\n case 0: return 'pixelated'\n case 1: return 'low'\n case 2: return 'medium'\n }\n return 'high'\n}\n\nconst CIB_QUALITY_FILTERS: Filter[] = ['box', 'hamming', 'lanczos2', 'lanczos3']\n\nexport function cib_quality_filter (num: CibResizeQuality): Filter {\n return CIB_QUALITY_FILTERS[num]\n}\n\nexport function is_cib_filter (filter: Filter): boolean {\n return CIB_QUALITY_FILTERS.indexOf(filter) >= 0\n}\n\nexport function filter_to_cib_quality (filter: Filter): CibResizeQuality | undefined {\n const index = CIB_QUALITY_FILTERS.indexOf(filter)\n\n return index >= 0 ? index as CibResizeQuality : undefined\n}\n\ntype ResizeQuality = 'pixelated' | 'low' | 'medium' | 'high'\n","export type Stage = [width: number, height: number]\n\n// Add intermediate resizing steps when scaling down by a very large factor.\n//\n// For example, when resizing 10000x10000 down to 10x10, it'll resize it to\n// 300x300 first.\n//\n// It's needed because tiler has issues when the entire tile is scaled down\n// to a few pixels (1024px source tile with border size 3 should result in\n// at least 3+3+2 = 8px target tile, so max scale factor is 128 here).\n//\n// Also, adding intermediate steps can speed up processing if we use lower\n// quality algorithms for first stages.\n//\n\n// min size = 0 results in infinite loop,\n// min size = 1 can consume large amount of memory\nconst MIN_INNER_TILE_SIZE = 2\n\nconst DEST_TILE_BORDER = 3 // Max possible filter window size\n\nexport default function createStages (\n fromWidth: number,\n fromHeight: number,\n toWidth: number,\n toHeight: number,\n srcTileSize: number\n): Stage[] {\n const scaleX = toWidth / fromWidth\n const scaleY = toHeight / fromHeight\n\n // derived from createRegions equation:\n // innerTileWidth = pixelFloor(srcTileSize * scaleX) - 2 * destTileBorder;\n const minScale = (2 * DEST_TILE_BORDER + MIN_INNER_TILE_SIZE + 1) / srcTileSize\n\n // refuse to scale image multiple times by less than twice each time,\n // it could only happen because of invalid options\n if (minScale > 0.5) return [[toWidth, toHeight]]\n\n const stageCount = Math.ceil(Math.log(Math.min(scaleX, scaleY)) / Math.log(minScale))\n\n // no additional resizes are necessary,\n // stageCount can be zero or be negative when enlarging the image\n if (stageCount <= 1) return [[toWidth, toHeight]]\n\n const result: Stage[] = []\n\n for (let i = 0; i < stageCount; i++) {\n const width = Math.round(\n Math.pow(\n Math.pow(fromWidth, stageCount - i - 1) * Math.pow(toWidth, i + 1),\n 1 / stageCount\n )\n )\n\n const height = Math.round(\n Math.pow(\n Math.pow(fromHeight, stageCount - i - 1) * Math.pow(toHeight, i + 1),\n 1 / stageCount\n )\n )\n\n result.push([width, height])\n }\n\n return result\n}\n","export interface Tile {\n toX: number\n toY: number\n toWidth: number\n toHeight: number\n toInnerX: number\n toInnerY: number\n toInnerWidth: number\n toInnerHeight: number\n offsetX: number\n offsetY: number\n scaleX: number\n scaleY: number\n x: number\n y: number\n width: number\n height: number\n}\n\nexport interface TilerOptions {\n width: number\n height: number\n srcTileSize: number\n toWidth: number\n toHeight: number\n destTileBorder: number\n}\n\n// Split original image into multiple 1024x1024 chunks to reduce memory usage\n// (images have to be unpacked into typed arrays for resizing) and allow\n// parallel processing of multiple tiles at a time.\n//\n\n/*\n * pixelFloor and pixelCeil are modified versions of Math.floor and Math.ceil\n * functions which take into account floating point arithmetic errors.\n * Those errors can cause undesired increments/decrements of sizes and offsets:\n * Math.ceil(36 / (36 / 500)) = 501\n * pixelCeil(36 / (36 / 500)) = 500\n */\n\nconst PIXEL_EPSILON = 1e-5\n\nfunction pixelFloor (x: number): number {\n const nearest = Math.round(x)\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) { return nearest }\n return Math.floor(x)\n}\n\nfunction pixelCeil (x: number): number {\n const nearest = Math.round(x)\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) { return nearest }\n return Math.ceil(x)\n}\n\nexport default function createRegions (options: TilerOptions): Tile[] {\n const scaleX = options.toWidth / options.width\n const scaleY = options.toHeight / options.height\n\n const innerTileWidth = pixelFloor(options.srcTileSize * scaleX) - 2 * options.destTileBorder\n const innerTileHeight = pixelFloor(options.srcTileSize * scaleY) - 2 * options.destTileBorder\n\n // prevent infinite loop, this should never happen\n if (innerTileWidth < 1 || innerTileHeight < 1) {\n throw new Error('Internal error in pica: target tile width/height is too small.')\n }\n\n let x, y\n let innerX, innerY, toTileWidth, toTileHeight\n const tiles: Tile[] = []\n let tile: Tile\n\n // we go top-to-bottom instead of left-to-right so the image is displayed\n // from top to bottom in the browser\n for (innerY = 0; innerY < options.toHeight; innerY += innerTileHeight) {\n for (innerX = 0; innerX < options.toWidth; innerX += innerTileWidth) {\n x = innerX - options.destTileBorder\n if (x < 0) { x = 0 }\n toTileWidth = innerX + innerTileWidth + options.destTileBorder - x\n if (x + toTileWidth >= options.toWidth) {\n toTileWidth = options.toWidth - x\n }\n\n y = innerY - options.destTileBorder\n if (y < 0) { y = 0 }\n toTileHeight = innerY + innerTileHeight + options.destTileBorder - y\n if (y + toTileHeight >= options.toHeight) {\n toTileHeight = options.toHeight - y\n }\n\n tile = {\n toX: x,\n toY: y,\n toWidth: toTileWidth,\n toHeight: toTileHeight,\n\n toInnerX: innerX,\n toInnerY: innerY,\n toInnerWidth: innerTileWidth,\n toInnerHeight: innerTileHeight,\n\n offsetX: x / scaleX - pixelFloor(x / scaleX),\n offsetY: y / scaleY - pixelFloor(y / scaleY),\n scaleX,\n scaleY,\n\n x: pixelFloor(x / scaleX),\n y: pixelFloor(y / scaleY),\n width: pixelCeil(toTileWidth / scaleX),\n height: pixelCeil(toTileHeight / scaleY)\n }\n\n tiles.push(tile)\n }\n }\n\n return tiles\n}\n","import type { PicaCanvas, PicaCanvasCtx } from './types'\n\nexport interface SupportedFeatures {\n canvas: boolean\n offscreen_canvas: boolean\n may_be_worker: boolean\n create_image_bitmap: boolean\n safari_put_image_data_fix: boolean\n bug_canvas_orientation_region: boolean\n bug_image_bitmap_orientation_region: boolean\n cib_resize: boolean\n}\n\n// 3x2 JPEG with EXIF orientation 6 (rotate 90deg clockwise when decoded).\n//\n// Stored pixels, before orientation (Black, White):\n//\n// B W B\n// B B B\n//\n// After orientation is applied, decoded image should be 2x3:\n//\n// B B\n// B W <- pixel at (1, 1) should be white if region crop is correct\n// B B\n//\n// If crop coordinates are applied before orientation, region (1, 1, 1, 1)\n// returns black instead. The checks below use this to detect region/orientation\n// bugs in canvas drawImage() and createImageBitmap().\nconst ORIENTED_JPEG_BASE64 =\n '/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/4AAQskZJRgABAQAAA' +\n 'QABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCw' +\n 'kJDRENDg8QEBEQCgwSExIQEw8QEBD/wAALCAACAAMBAREA/8QAFAABAAAAAAAAAAAAAAAA' +\n 'AAAACf/EABsQAAMBAQADAAAAAAAAAAAAAAECAwQFABEx/9oACAEBAAA/AC06fW6va0ps' +\n '7PT179E88MiV02arrCEkjGQZiSEnKc5ovxURVHoADz//2Q=='\n\nconst features: SupportedFeatures = {\n canvas: false,\n offscreen_canvas: false,\n may_be_worker: false,\n create_image_bitmap: false,\n safari_put_image_data_fix: false,\n bug_canvas_orientation_region: true,\n bug_image_bitmap_orientation_region: true,\n cib_resize: false\n}\n\nlet checked = false\nlet checking: Promise<SupportedFeatures> | null = null\n\nconst ctxOpts: CanvasRenderingContext2DSettings = { willReadFrequently: true }\n\nfunction check_canvas (): boolean {\n if (typeof document === 'undefined' || !document.createElement) return false\n\n try {\n const canvas = document.createElement('canvas')\n canvas.width = 2\n canvas.height = 1\n\n const ctx = canvas.getContext('2d', ctxOpts)!\n\n // Fingerprinting protection can randomize readback.\n // In that case we can not rely on canvas pixel data.\n let d = ctx.createImageData(2, 1)\n\n d.data[0] = 12; d.data[1] = 23; d.data[2] = 34; d.data[3] = 255\n d.data[4] = 45; d.data[5] = 56; d.data[6] = 67; d.data[7] = 255\n ctx.putImageData(d, 0, 0)\n d = ctx.getImageData(0, 0, 2, 1)\n\n return d.data[0] === 12 && d.data[1] === 23 && d.data[2] === 34 && d.data[3] === 255 &&\n d.data[4] === 45 && d.data[5] === 56 && d.data[6] === 67 && d.data[7] === 255\n } catch (__) {\n return false\n }\n}\n\nfunction check_offscreen_canvas (): boolean {\n if (typeof OffscreenCanvas === 'undefined') return false\n\n try {\n const canvas = new OffscreenCanvas(2, 1)\n const ctx = canvas.getContext('2d', ctxOpts)!\n\n // Fingerprinting protection can randomize readback.\n // In that case we can not rely on canvas pixel data.\n let d = ctx.createImageData(2, 1)\n\n d.data[0] = 12; d.data[1] = 23; d.data[2] = 34; d.data[3] = 255\n d.data[4] = 45; d.data[5] = 56; d.data[6] = 67; d.data[7] = 255\n ctx.putImageData(d, 0, 0)\n d = ctx.getImageData(0, 0, 2, 1)\n\n return d.data[0] === 12 && d.data[1] === 23 && d.data[2] === 34 && d.data[3] === 255 &&\n d.data[4] === 45 && d.data[5] === 56 && d.data[6] === 67 && d.data[7] === 255\n } catch (__) {\n return false\n }\n}\n\nfunction check_create_image_bitmap (): boolean {\n return typeof createImageBitmap !== 'undefined'\n}\n\nfunction check_may_be_worker (): boolean {\n return typeof Worker !== 'undefined' &&\n // Filter out IE <= 11 for sure\n (typeof URL !== 'undefined' && !!URL.createObjectURL)\n}\n\nfunction check_safari_put_image_data_fix (): boolean {\n try {\n return !!(typeof navigator !== 'undefined' &&\n navigator.userAgent &&\n navigator.userAgent.indexOf('Safari') >= 0 &&\n navigator.userAgent.indexOf('Chrome') < 0)\n } catch (__) {\n return false\n }\n}\n\nfunction check_bug_canvas_orientation_region_async (): Promise<boolean> {\n return Promise.resolve().then(() => {\n const canOffscreenCanvas = check_offscreen_canvas() &&\n check_create_image_bitmap() &&\n typeof Blob !== 'undefined' &&\n typeof atob !== 'undefined'\n\n if (canOffscreenCanvas) {\n const binary = atob(ORIENTED_JPEG_BASE64)\n const bytes = new Uint8Array(binary.length)\n\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n\n return createImageBitmap(new Blob([bytes], { type: 'image/jpeg' }))\n .then(bitmap => {\n const canvas = new OffscreenCanvas(1, 1)\n\n try {\n const ctx = canvas.getContext('2d', ctxOpts)!\n ctx.drawImage(bitmap, 1, 1, 1, 1, 0, 0, 1, 1)\n\n return ctx.getImageData(0, 0, 1, 1).data[0] < 240\n } finally {\n bitmap.close()\n }\n })\n }\n\n if (check_canvas() && typeof Image !== 'undefined') {\n return new Promise<boolean>(resolve => {\n const image = new Image()\n\n image.onload = () => {\n try {\n const canvas = document.createElement('canvas')\n canvas.width = 1\n canvas.height = 1\n\n const ctx = canvas.getContext('2d', ctxOpts)!\n ctx.drawImage(image, 1, 1, 1, 1, 0, 0, 1, 1)\n\n resolve(ctx.getImageData(0, 0, 1, 1).data[0] < 240)\n } catch (__) {\n resolve(true)\n }\n }\n\n image.onerror = () => resolve(true)\n image.src = `data:image/jpeg;base64,${ORIENTED_JPEG_BASE64}`\n })\n }\n\n return true\n })\n .catch(() => true)\n}\n\nfunction check_bug_image_bitmap_orientation_region_async (): Promise<boolean> {\n return Promise.resolve().then(() => {\n if (!features.create_image_bitmap && !check_create_image_bitmap()) return true\n if (typeof Blob === 'undefined' || typeof atob === 'undefined') return true\n\n const canOffscreenCanvas = check_offscreen_canvas()\n const canCanvas = check_canvas()\n\n if (!canOffscreenCanvas && !canCanvas) return true\n\n const binary = atob(ORIENTED_JPEG_BASE64)\n const bytes = new Uint8Array(binary.length)\n\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n\n return createImageBitmap(new Blob([bytes], { type: 'image/jpeg' }))\n .then(imageBitmap => createImageBitmap(imageBitmap, 1, 1, 1, 1)\n .then(bitmap => {\n let canvas: PicaCanvas\n\n if (canOffscreenCanvas) {\n canvas = new OffscreenCanvas(1, 1)\n } else {\n canvas = document.createElement('canvas')\n canvas.width = 1\n canvas.height = 1\n }\n\n try {\n const ctx = canvas.getContext('2d', ctxOpts) as PicaCanvasCtx\n ctx.drawImage(bitmap, 0, 0)\n\n return bitmap.width !== 1 || bitmap.height !== 1 ||\n ctx.getImageData(0, 0, 1, 1).data[0] < 240\n } finally {\n imageBitmap.close()\n bitmap.close()\n }\n }, () => {\n imageBitmap.close()\n return true\n }))\n })\n .catch(() => true)\n}\n\nfunction check_cib_resize_async (): Promise<boolean> {\n return Promise.resolve().then(() => {\n if (!check_create_image_bitmap()) return false\n\n const SRC_SIZE = 20\n const DST_SIZE = 5\n\n let canvas: PicaCanvas | null\n\n if (features.canvas || check_canvas()) {\n canvas = document.createElement('canvas')\n canvas.width = SRC_SIZE\n canvas.height = SRC_SIZE\n } else if (features.offscreen_canvas || check_offscreen_canvas()) {\n canvas = new OffscreenCanvas(SRC_SIZE, SRC_SIZE)\n // Chrome fails to createImageBitmap() from canvas without drawing\n // anything on it.\n const ctx = canvas.getContext('2d', ctxOpts)!\n ctx.clearRect(0, 0, SRC_SIZE, SRC_SIZE)\n } else {\n return false\n }\n\n return createImageBitmap(canvas, 0, 0, SRC_SIZE, SRC_SIZE, {\n resizeWidth: DST_SIZE,\n resizeHeight: DST_SIZE,\n resizeQuality: 'high'\n })\n .then(bitmap => {\n const status = bitmap.width === DST_SIZE && !!bitmap.close\n\n if (bitmap.close) bitmap.close()\n canvas = null\n return status\n })\n })\n .catch(() => false)\n}\n\nexport function get_supported_features (): Promise<SupportedFeatures> {\n if (checked) return Promise.resolve(Object.assign({}, features))\n if (checking) return checking.then(() => Object.assign({}, features))\n\n features.canvas = check_canvas()\n features.offscreen_canvas = check_offscreen_canvas()\n features.may_be_worker = check_may_be_worker()\n features.create_image_bitmap = check_create_image_bitmap()\n features.safari_put_image_data_fix = check_safari_put_image_data_fix()\n\n const bugCanvasOrientationRegion = check_bug_canvas_orientation_region_async()\n .then(result => { features.bug_canvas_orientation_region = result })\n .catch(() => {})\n\n const bugImageBitmapOrientationRegion = check_bug_image_bitmap_orientation_region_async()\n .then(result => { features.bug_image_bitmap_orientation_region = result })\n .catch(() => {})\n\n const cibResize = check_cib_resize_async()\n .then(result => { features.cib_resize = result })\n .catch(() => {})\n\n checking = Promise.all([\n bugCanvasOrientationRegion,\n bugImageBitmapOrientationRegion,\n cibResize\n ]).then(() => {\n checked = true\n checking = null\n return Object.assign({}, features)\n }, err => {\n checking = null\n throw err\n })\n\n return checking\n}\n","import MathLib, { type MathResizeAndUnsharpOptions } from './mathlib'\nimport Pool from './pool'\nimport * as utils from './utils'\nimport createStages from './stepper'\nimport createRegions, { type Tile } from './tiler'\nimport * as supported_features from './supported_features'\nimport type {\n Capabilities,\n CreateCanvasPreference,\n PicaFeaturesFlat,\n Filter,\n Limiter,\n PicaCanvas,\n PicaCanvasCtx,\n PicaOptions,\n PicaSource,\n ResizeBufferOptions,\n ResizeContext,\n ResizeFeaturesMap,\n ResizeParams,\n TileResizeJob,\n TileResizeJobBase,\n ResizeOptions,\n ResizeResult,\n ResolvedPicaOptions,\n StageEnv,\n WorkerFeaturesResult,\n WorkerMethod,\n WorkerResizePayload\n} from './types'\n\nexport type {\n PicaFeaturesFlat,\n Filter,\n PicaCanvas,\n PicaOptions,\n PicaSource,\n ResizeBufferOptions,\n ResizeOptions,\n CibResizeQuality\n} from './types'\n\ndeclare const __PICA_WORKER_SRC__: string | undefined\n\nconst WORKER_SRC = typeof __PICA_WORKER_SRC__ !== 'undefined' ? __PICA_WORKER_SRC__ : ''\n\nlet concurrency = 1\nif (typeof navigator !== 'undefined') {\n concurrency = Math.min(navigator.hardwareConcurrency || 1, 4)\n}\n\nconst DEFAULT_PICA_OPTS: ResolvedPicaOptions = {\n tile: 1024,\n concurrency,\n features: ['js', 'wasm', 'ww'],\n idle: 2000,\n}\n\nconst DEFAULT_RESIZE_OPTS = {\n filter: 'mks2013',\n unsharpAmount: 0,\n unsharpRadius: 0.0,\n unsharpThreshold: 0\n}\n\nconst ctxOpts: CanvasRenderingContext2DSettings = { willReadFrequently: true }\n\n// //////////////////////////////////////////////////////////////////////////////\n// API methods\n\nexport class Pica {\n private options: ResolvedPicaOptions\n private __limit: Limiter\n private resize_features: ResizeFeaturesMap\n private __workersPool: Pool<Worker> | null\n private capabilities: Capabilities\n private __requested_features: PicaFeaturesFlat\n private __mathlib: MathLib | null\n private __initPromise?: Promise<this>\n\n constructor (options?: PicaOptions) {\n this.options = Object.assign({}, DEFAULT_PICA_OPTS, options || {})\n\n const workerRequested = this.options.features.indexOf('ww') >= 0 || this.options.features.indexOf('all') >= 0\n\n if (workerRequested && !this.options.workerURL && !WORKER_SRC) {\n throw new Error('Pica: cannot use WebWorker without workerURL')\n }\n\n this.__limit = utils.limiter(this.options.concurrency)\n\n // List of enabled resize methods, according to options & browser/node.js\n this.resize_features = {\n js: false, // pure JS implementation, can be disabled for testing\n wasm: false, // webassembly implementation for heavy functions\n cib: false, // resize via createImageBitmap (only FF at this moment)\n ww: false // webworkers\n }\n\n this.__workersPool = null\n this.capabilities = {\n worker: false,\n ww_offscreen_canvas: false,\n canvas: false,\n offscreen_canvas: false,\n may_be_worker: false,\n create_image_bitmap: false,\n safari_put_image_data_fix: false,\n bug_canvas_orientation_region: true,\n bug_image_bitmap_orientation_region: true,\n cib_resize: false\n }\n\n // Store requested features for webworkers\n this.__requested_features = []\n\n this.__mathlib = null\n }\n\n init (): Promise<this> {\n if (this.__initPromise) return this.__initPromise\n\n this.__initPromise = this.__init()\n\n return this.__initPromise\n }\n\n private async __init (): Promise<this> {\n let features = this.options.features.slice()\n\n if (features.indexOf('all') >= 0) {\n features = ['cib', 'wasm', 'js', 'ww']\n }\n\n this.__requested_features = features\n\n this.__mathlib = new MathLib(features)\n\n const result = await supported_features.get_supported_features()\n Object.assign(this.capabilities, result)\n\n if (this.capabilities.cib_resize && features.indexOf('cib') >= 0) {\n this.resize_features.cib = true\n }\n\n // Check WebWorker support if requested\n if (this.capabilities.may_be_worker && features.indexOf('ww') >= 0 && (WORKER_SRC || this.options.workerURL)) {\n this.__workersPool = new Pool(() => this.__createWorkerSlot(), this.options.idle)\n }\n\n if (this.__workersPool) {\n try {\n const result = await this.__invokeWorker<WorkerFeaturesResult>('get_supported_features')\n const resultData = result && result.data\n if (resultData) {\n this.capabilities.worker = true\n this.resize_features.ww = true\n this.capabilities.ww_offscreen_canvas = !!resultData.offscreen_canvas\n }\n } catch (__) {}\n }\n\n const mathlib = await this.__mathlib.init()\n // Copy detected resize methods\n Object.assign(this.resize_features, mathlib.features)\n\n return this\n }\n\n createCanvas (width: number, height: number, preferOffscreen?: CreateCanvasPreference): PicaCanvas {\n if (preferOffscreen && this.capabilities.offscreen_canvas) {\n return new OffscreenCanvas(width, height)\n }\n\n if (this.capabilities.canvas) {\n const canvas = document.createElement('canvas')\n canvas.width = width\n canvas.height = height\n return canvas\n }\n\n if (this.capabilities.ww_offscreen_canvas) {\n return new OffscreenCanvas(width, height)\n }\n\n throw new Error('Pica: cannot create canvas')\n }\n\n private __createWorkerSlot (): { value: Worker, destroy: () => void } {\n if (this.options.workerURL) {\n const worker = new Worker(String(this.options.workerURL))\n return { value: worker, destroy () { worker.terminate() } }\n }\n\n if (WORKER_SRC) {\n const objectURL = window.URL.createObjectURL(new Blob([WORKER_SRC], { type: 'text/javascript' }))\n const worker = new Worker(objectURL)\n return {\n value: worker,\n destroy () {\n worker.terminate()\n if (typeof window !== 'undefined') {\n window.URL?.revokeObjectURL?.(objectURL)\n }\n }\n }\n }\n\n throw new Error('Pica: no worker source available')\n }\n\n // Call resizer in webworker or locally, depending on config\n private __invokeWorker<TResult> (\n method: WorkerMethod,\n payload?: Record<string, unknown>,\n transfer?: Transferable[],\n opts?: { cancelToken?: Promise<unknown> }\n ): Promise<TResult> {\n return new Promise((resolve, reject) => {\n const w = this.__workersPool!.acquire()\n\n if (opts && opts.cancelToken) opts.cancelToken.catch(err => reject(err))\n\n w.value.onmessage = ev => {\n w.release()\n\n if (ev.data.err) reject(ev.data.err)\n else resolve(ev.data)\n }\n\n w.value.postMessage(Object.assign({ method }, payload || {}), transfer || [])\n })\n }\n\n private async __invokeResize (tileJob: TileResizeJob, ctx: ResizeContext): Promise<ResizeResult> {\n await Promise.resolve()\n\n if (!this.resize_features.ww) {\n // not possible to have ImageBitmap here if user disabled WW\n if (tileJob.kind !== 'array') throw new Error('Pica: resize tile data is missing')\n\n const mathOpts: MathResizeAndUnsharpOptions = {\n src: tileJob.src,\n width: tileJob.width,\n height: tileJob.height,\n toWidth: tileJob.toWidth,\n toHeight: tileJob.toHeight,\n scaleX: tileJob.scaleX,\n scaleY: tileJob.scaleY,\n offsetX: tileJob.offsetX,\n offsetY: tileJob.offsetY,\n filter: tileJob.filter,\n unsharpAmount: tileJob.unsharpAmount,\n unsharpRadius: tileJob.unsharpRadius,\n unsharpThreshold: tileJob.unsharpThreshold\n }\n\n return { kind: 'array', data: this.__mathlib!.resizeAndUnsharp(mathOpts) }\n }\n\n const transfer = []\n\n if (tileJob.kind === 'array') transfer.push(tileJob.src.buffer)\n else transfer.push(tileJob.src)\n\n return this.__invokeWorker<ResizeResult>(\n 'resize',\n {\n job: tileJob,\n features: this.__requested_features\n } satisfies Omit<WorkerResizePayload, 'method'>,\n transfer,\n ctx\n )\n }\n\n // this function can return promise if createImageBitmap is used\n private __extractTileData (\n tile: Tile,\n from: PicaSource,\n stageEnv: StageEnv,\n extractTo: TileResizeJobBase\n ): TileResizeJob {\n if (this.resize_features.ww && this.capabilities.ww_offscreen_canvas) {\n this.debug('Create tile imageBitmap')\n\n const tileCanvas = this.createCanvas(tile.width, tile.height, { preferOffscreen: true })\n const tileCtx = tileCanvas.getContext('2d', ctxOpts) as PicaCanvasCtx\n\n tileCtx.drawImage(stageEnv.srcImageBitmap || from,\n tile.x, tile.y, tile.width, tile.height,\n 0, 0, tile.width, tile.height)\n\n if (!('transferToImageBitmap' in tileCanvas)) {\n throw new Error('Pica: offscreen canvas is not available for worker transfer')\n }\n\n return Object.assign({}, extractTo, {\n kind: 'bitmap' as const,\n src: tileCanvas.transferToImageBitmap()\n })\n\n // Direct region extraction, intentionally disabled. This can be faster,\n // but has known EXIF orientation bugs in some browsers.\n //\n // return createImageBitmap(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height)\n // .then(bitmap => {\n // extractTo.src = bitmap;\n // return extractTo;\n // });\n }\n\n // Extract tile RGBA buffer, depending on input type\n if (utils.isCanvas(from)) {\n if (!stageEnv.srcCtx) stageEnv.srcCtx = from.getContext('2d', ctxOpts) as PicaCanvasCtx\n\n // If input is Canvas - extract region data directly\n this.debug('Get tile pixel data')\n return Object.assign({}, extractTo, {\n kind: 'array' as const,\n src: stageEnv.srcCtx.getImageData(tile.x, tile.y, tile.width, tile.height).data\n })\n }\n\n // If input is Image or decoded to ImageBitmap,\n // draw region to temporary canvas and extract data from it\n //\n // Note! Attempt to reuse this canvas causes significant slowdown in chrome\n //\n this.debug('Draw tile imageBitmap/image to temporary canvas')\n\n const tmpCanvas = this.createCanvas(tile.width, tile.height, { preferOffscreen: true })\n\n const tmpCtx = tmpCanvas.getContext('2d', ctxOpts) as PicaCanvasCtx\n tmpCtx.globalCompositeOperation = 'copy'\n tmpCtx.drawImage(stageEnv.srcImageBitmap || from,\n tile.x, tile.y, tile.width, tile.height,\n 0, 0, tile.width, tile.height)\n\n this.debug('Get tile pixel data')\n\n const src = tmpCtx.getImageData(0, 0, tile.width, tile.height).data\n\n // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n tmpCanvas.width = tmpCanvas.height = 0\n\n return Object.assign({}, extractTo, {\n kind: 'array' as const,\n src\n })\n }\n\n private __landTileData (tile: Tile, result: ResizeResult, stageEnv: StageEnv): null {\n if (result.kind === 'bitmap') {\n stageEnv.toCtx!.drawImage(result.data, tile.toX, tile.toY)\n result.data.close()\n return null\n }\n\n this.debug('Draw tile')\n\n const toImageData = stageEnv.toCtx!.createImageData(tile.toWidth, tile.toHeight)\n toImageData.data.set(result.data)\n\n if (this.capabilities.safari_put_image_data_fix) {\n // Safari draws thin white stripes between tiles without this fix\n stageEnv.toCtx!.putImageData(toImageData, tile.toX, tile.toY,\n tile.toInnerX - tile.toX, tile.toInnerY - tile.toY,\n tile.toInnerWidth + 1e-5, tile.toInnerHeight + 1e-5)\n } else {\n stageEnv.toCtx!.putImageData(toImageData, tile.toX, tile.toY,\n tile.toInnerX - tile.toX, tile.toInnerY - tile.toY,\n tile.toInnerWidth, tile.toInnerHeight)\n }\n\n return null\n }\n\n private async __tileAndResize (\n from: PicaSource,\n to: PicaCanvas,\n resizeParams: ResizeParams,\n ctx: ResizeContext\n ): Promise<PicaCanvas> {\n const stageEnv: StageEnv = {\n srcCtx: null,\n srcImageBitmap: null,\n isImageBitmapReused: false,\n toCtx: null\n }\n\n const processTile = (tile: Tile) => this.__limit(async () => {\n if (ctx.canceled) return ctx.cancelToken\n\n const tileJob: TileResizeJobBase = {\n width: tile.width,\n height: tile.height,\n toWidth: tile.toWidth,\n toHeight: tile.toHeight,\n scaleX: tile.scaleX,\n scaleY: tile.scaleY,\n offsetX: tile.offsetX,\n offsetY: tile.offsetY,\n filter: resizeParams.filter,\n unsharpAmount: resizeParams.unsharpAmount,\n unsharpRadius: resizeParams.unsharpRadius,\n unsharpThreshold: resizeParams.unsharpThreshold\n }\n\n this.debug('Invoke resize math')\n\n const extractedTileJob = await this.__extractTileData(tile, from, stageEnv, tileJob)\n\n this.debug('Invoke resize math')\n const result = await this.__invokeResize(extractedTileJob, ctx)\n\n if (ctx.canceled) return ctx.cancelToken\n return this.__landTileData(tile, result, stageEnv)\n })\n\n // Need to normalize data source first. It can be canvas or image.\n // If image - try to decode in background if possible\n await Promise.resolve()\n\n stageEnv.toCtx = to.getContext('2d', ctxOpts) as PicaCanvasCtx\n\n if (utils.isCanvas(from)) {\n // Source is ready as-is.\n } else if (utils.isImageBitmap(from)) {\n stageEnv.srcImageBitmap = from\n stageEnv.isImageBitmapReused = true\n } else if (utils.isImage(from)) {\n // try to decode image in background for faster next operations;\n // if we're using offscreen canvas, cib is called per tile, so not needed here\n if (this.capabilities.create_image_bitmap) {\n this.debug('Decode image via createImageBitmap')\n\n // Suppress error to use fallback, if method fails\n // https://github.com/nodeca/pica/issues/190\n try {\n stageEnv.srcImageBitmap = await createImageBitmap(from)\n } catch (__) {}\n }\n } else {\n throw new Error('Pica: \".from\" should be Image, Canvas or ImageBitmap')\n }\n\n if (ctx.canceled) return ctx.cancelToken as Promise<PicaCanvas>\n\n this.debug('Calculate tiles')\n\n //\n // Here we are with \"normalized\" source,\n // follow to tiling\n //\n\n const regions = createRegions({\n width: resizeParams.width,\n height: resizeParams.height,\n srcTileSize: this.options.tile,\n toWidth: resizeParams.toWidth,\n toHeight: resizeParams.toHeight,\n destTileBorder: Math.ceil(Math.max(3, 2.5 * resizeParams.unsharpRadius | 0))\n })\n\n const jobs = regions.map(tile => processTile(tile))\n\n function cleanup (stageEnv: StageEnv) {\n if (stageEnv.srcImageBitmap) {\n if (!stageEnv.isImageBitmapReused) stageEnv.srcImageBitmap.close()\n stageEnv.srcImageBitmap = null\n }\n }\n\n this.debug('Process tiles')\n\n try {\n await Promise.all(jobs)\n this.debug('Finished!')\n cleanup(stageEnv)\n return to\n } catch (err) {\n cleanup(stageEnv)\n throw err\n }\n }\n\n private async __planStagesAndResize (\n from: PicaSource,\n to: PicaCanvas,\n resizeParams: ResizeParams,\n ctx: ResizeContext\n ): Promise<PicaCanvas> {\n let src: PicaSource = from\n let srcWidth = resizeParams.width\n let srcHeight = resizeParams.height\n\n const stages = createStages(\n resizeParams.width,\n resizeParams.height,\n resizeParams.toWidth,\n resizeParams.toHeight,\n this.options.tile\n )\n\n while (stages.length > 0) {\n if (ctx.canceled) return ctx.cancelToken as Promise<PicaCanvas>\n\n const [toWidth, toHeight] = stages.shift()!\n const isLastStage = stages.length === 0\n\n // Optimization for legacy filters -\n // only use user-defined quality for the last stage,\n // use simpler (Hamming) filter for the first stages where\n // scale factor is large enough (more than 2-3)\n //\n // For advanced filters (mks2013 and custom) - skip optimization,\n // because need to apply sharpening every time\n let filter: Filter\n if (isLastStage || !utils.is_cib_filter(resizeParams.filter)) filter = resizeParams.filter\n else if (resizeParams.filter === 'box') filter = 'box'\n else filter = 'hamming'\n\n const stageParams: ResizeParams = { ...resizeParams, filter, width: srcWidth, height: srcHeight, toWidth, toHeight }\n const dest = isLastStage ? to : this.createCanvas(toWidth, toHeight, { preferOffscreen: true })\n\n // Previous intermediate canvas (not the original `from`) can be freed after use\n const prevTmp = src !== from ? src as PicaCanvas : undefined\n\n try {\n await this.__tileAndResize(src, dest, stageParams, ctx)\n } finally {\n // Safari 12 workaround: https://github.com/nodeca/pica/issues/199\n if (prevTmp) prevTmp.width = prevTmp.height = 0\n }\n\n src = dest\n srcWidth = toWidth\n srcHeight = toHeight\n }\n\n return to\n }\n\n private async __resizeViaCreateImageBitmap (\n from: PicaSource,\n to: PicaCanvas,\n resizeParams: ResizeParams,\n ctx: ResizeContext\n ): Promise<PicaCanvas> {\n let toCtx: PicaCanvasCtx | null = to.getContext('2d', ctxOpts) as PicaCanvasCtx\n\n this.debug('Resize via createImageBitmap()')\n\n const imageBitmap = await createImageBitmap(from, {\n resizeWidth: resizeParams.toWidth,\n resizeHeight: resizeParams.toHeight,\n resizeQuality: utils.cib_quality_name(utils.filter_to_cib_quality(resizeParams.filter) ?? 3)\n })\n if (ctx.canceled) return ctx.cancelToken as Promise<PicaCanvas>\n\n // if no unsharp - draw directly to output canvas\n if (!resizeParams.unsharpAmount) {\n toCtx.drawImage(imageBitmap, 0, 0)\n imageBitmap.close()\n toCtx = null\n\n this.debug('Finished!')\n\n return to\n }\n\n this.debug('Unsharp result')\n\n let tmpCanvas: PicaCanvas | null = this.createCanvas(resizeParams.toWidth, resizeParams.toHeight)\n\n let tmpCtx: PicaCanvasCtx | null = tmpCanvas.getContext('2d', ctxOpts) as PicaCanvasCtx\n\n tmpCtx.drawImage(imageBitmap, 0, 0)\n imageBitmap.close()\n\n let iData: ImageData | null = tmpCtx.getImageData(0, 0, resizeParams.toWidth, resizeParams.toHeight)\n\n this.__mathlib!.unsharp_mask(\n iData.data,\n resizeParams.toWidth,\n resizeParams.toHeight,\n resizeParams.unsharpAmount,\n resizeParams.unsharpRadius,\n resizeParams.unsharpThreshold\n )\n\n toCtx.putImageData(iData, 0, 0)\n\n // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n tmpCanvas.width = tmpCanvas.height = 0\n\n iData = tmpCtx = tmpCanvas = toCtx = null\n\n this.debug('Finished!')\n\n return to\n }\n\n async resize<TCanvas extends PicaCanvas> (\n from: PicaSource,\n to: TCanvas,\n options?: ResizeOptions\n ): Promise<TCanvas> {\n this.debug('Start resize...')\n\n const requested: ResizeOptions = {}\n\n if (options) {\n Object.assign(requested, options)\n }\n\n let filter: Filter = (requested.filter || DEFAULT_RESIZE_OPTS.filter) as Filter\n\n // Legacy `.quality` option\n if (Object.prototype.hasOwnProperty.call(requested, 'quality')) {\n const quality = requested.quality\n if (typeof quality !== 'number' || quality < 0 || quality > 3) {\n throw new Error(`Pica: .quality should be [0..3], got ${quality}`)\n }\n filter = utils.cib_quality_filter(quality)\n }\n\n const resizeParams: ResizeParams = {\n filter,\n unsharpAmount: requested.unsharpAmount || DEFAULT_RESIZE_OPTS.unsharpAmount,\n unsharpRadius: requested.unsharpRadius || DEFAULT_RESIZE_OPTS.unsharpRadius,\n unsharpThreshold: requested.unsharpThreshold || DEFAULT_RESIZE_OPTS.unsharpThreshold,\n width: utils.isImage(from) ? from.naturalWidth : from.width,\n height: utils.isImage(from) ? from.naturalHeight : from.height,\n toWidth: to.width,\n toHeight: to.height\n }\n\n if (resizeParams.unsharpRadius > 2) resizeParams.unsharpRadius = 2\n\n // Prevent stepper from infinite loop\n if (to.width === 0 || to.height === 0) {\n return Promise.reject(new Error(`Invalid output size: ${to.width}x${to.height}`))\n }\n\n const ctx: ResizeContext = {\n cancelToken: requested.cancelToken,\n canceled: false\n }\n\n if (ctx.cancelToken) {\n // Wrap cancelToken to avoid successive resolve & set flag\n ctx.cancelToken = ctx.cancelToken.then(\n data => { ctx.canceled = true; throw data },\n err => { ctx.canceled = true; throw err }\n )\n }\n\n await this.init()\n\n if (ctx.canceled) return ctx.cancelToken as Promise<TCanvas>\n\n // createImageBitmap doesn't work for images (Image, ImageBitmap) with\n // Exif orientation in Chrome. Enforce canvas use for such inputs.\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n if (this.capabilities.bug_image_bitmap_orientation_region &&\n (utils.isImage(from) || (utils.isImageBitmap(from)))) {\n const tmpCanvas = this.createCanvas(resizeParams.width, resizeParams.height)\n const tmpCtx = tmpCanvas.getContext('2d', ctxOpts) as PicaCanvasCtx\n tmpCtx.drawImage(from, 0, 0)\n from = tmpCanvas\n }\n\n // if createImageBitmap supports resize, just do it and return\n if (this.resize_features.cib) {\n if (utils.is_cib_filter(resizeParams.filter)) {\n return this.__resizeViaCreateImageBitmap(from, to, resizeParams, ctx) as Promise<TCanvas>\n }\n\n this.debug('cib is enabled, but not supports provided filter, fallback to manual math')\n }\n\n if (!this.capabilities.canvas && !this.capabilities.offscreen_canvas) {\n const err = new Error('Pica: cannot use getImageData on canvas, ' +\n \"make sure fingerprinting protection isn't enabled\")\n // @ts-ignore\n err.code = 'ERR_GET_IMAGE_DATA'\n throw err\n }\n\n //\n // No easy way, let's resize manually via arrays\n //\n\n return this.__planStagesAndResize(from, to, resizeParams, ctx) as Promise<TCanvas>\n }\n\n // RGBA buffer resize\n //\n async resizeBuffer (options: ResizeBufferOptions): Promise<Uint8Array> {\n const opts = Object.assign({}, DEFAULT_RESIZE_OPTS, options)\n\n // Legacy `.quality` option\n if (Object.prototype.hasOwnProperty.call(opts, 'quality')) {\n const quality = opts.quality\n if (typeof quality !== 'number' || quality < 0 || quality > 3) {\n throw new Error(`Pica: .quality should be [0..3], got ${quality}`)\n }\n opts.filter = utils.cib_quality_filter(quality)\n }\n\n await this.init()\n if (!this.__mathlib) throw new Error('Pica: math library is not initialized')\n\n const mathOpts: MathResizeAndUnsharpOptions = {\n src: opts.src,\n width: opts.width,\n height: opts.height,\n toWidth: opts.toWidth,\n toHeight: opts.toHeight,\n dest: opts.dest,\n scaleX: opts.toWidth / opts.width,\n scaleY: opts.toHeight / opts.height,\n offsetX: 0,\n offsetY: 0,\n filter: opts.filter,\n unsharpAmount: opts.unsharpAmount,\n unsharpRadius: opts.unsharpRadius,\n unsharpThreshold: opts.unsharpThreshold\n }\n\n return this.__mathlib.resizeAndUnsharp(mathOpts)\n }\n\n async toBlob (canvas: HTMLCanvasElement | OffscreenCanvas, mimeType?: string, quality?: number): Promise<Blob> {\n mimeType = mimeType || 'image/png'\n\n // Ordinary Canvas\n if ('toBlob' in canvas && canvas.toBlob) {\n return new Promise(resolve => {\n canvas.toBlob(blob => resolve(blob as Blob), mimeType, quality)\n })\n }\n\n // OffscreenCanvas\n if ('convertToBlob' in canvas && canvas.convertToBlob) {\n return canvas.convertToBlob({\n type: mimeType,\n quality\n })\n }\n\n // Fallback for old browsers\n const asString = atob((canvas as HTMLCanvasElement).toDataURL(mimeType, quality).split(',')[1])\n const len = asString.length\n const asBuffer = new Uint8Array(len)\n\n for (let i = 0; i < len; i++) {\n asBuffer[i] = asString.charCodeAt(i)\n }\n\n return new Blob([asBuffer], { type: mimeType })\n }\n\n debug (..._args: unknown[]): void {}\n}\n\nexport default function pica (options?: PicaOptions): Pica {\n return new Pica(options)\n}\n"],"x_google_ignoreList":[3],"mappings":"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"}