UNPKG

@nuintun/qrcode

Version:

A pure JavaScript QRCode encode and decode library.

78 lines (73 loc) 2.65 kB
/** * @module QRCode * @package @nuintun/qrcode * @license MIT * @version 5.0.3 * @author nuintun <nuintun@qq.com> * @description A pure JavaScript QRCode encode and decode library. * @see https://github.com/nuintun/qrcode#readme */ 'use strict'; const utils = require('../../common/utils.cjs'); const constants = require('./constants.cjs'); const scanline = require('./scanline.cjs'); /** * @module pattern */ function isDiagonalScanlineCheckPassed(slash, backslash, ratios, strict) { return strict ? isMatchPattern(slash, ratios) && isMatchPattern(backslash, ratios) : isMatchPattern(slash, ratios) || isMatchPattern(backslash, ratios); } function alignCrossPattern(matrix, x, y, overscan, ratios, isVertical) { const [scanline$1, end] = scanline.getCrossScanline(matrix, x, y, overscan, isVertical); return [isMatchPattern(scanline$1, ratios) ? scanline.centerFromScanlineEnd(scanline$1, end) : NaN, scanline$1]; } function isEqualsSize(size1, size2, ratio) { if (size1 > size2) { [size1, size2] = [size2, size1]; } return size2 - size1 <= size2 * ratio; } function isMatchPattern(scanline$1, { ratios, modules }) { const { length } = scanline$1; const scanlineTotal = scanline.sumScanlineNonzero(scanline$1); if (scanlineTotal >= modules) { const moduleSize = scanlineTotal / modules; const threshold = moduleSize * constants.DIFF_PATTERN_RATIO + constants.DIFF_PATTERN_ALLOWANCE; // Allow less than DIFF_PATTERN_RATIO variance from 1-1-3-1-1 or 1-1-1-1-1 proportions. for (let i = 0; i < length; i++) { const ratio = ratios[i]; const count = scanline$1[i]; const countDiff = Math.abs(count - moduleSize * ratio); if (countDiff > threshold) { return false; } } return true; } return false; } function calculatePatternNoise(ratios, ...scanlines) { let noises = 0; let averageNoises = 0; const { length } = scanlines; const averages = []; // scanline length must be equals ratios length. for (const scanline$1 of scanlines) { const [noise, average] = scanline.calculateScanlineNoise(scanline$1, ratios); noises += noise; averages.push(average); } const total = utils.accumulate(averages); const averagesAvg = total / length; for (const average of averages) { averageNoises += Math.abs(average - averagesAvg); } return noises + averageNoises / total; } exports.alignCrossPattern = alignCrossPattern; exports.calculatePatternNoise = calculatePatternNoise; exports.isDiagonalScanlineCheckPassed = isDiagonalScanlineCheckPassed; exports.isEqualsSize = isEqualsSize; exports.isMatchPattern = isMatchPattern;