Skip to content

Commit

Permalink
feat: Update core
Browse files Browse the repository at this point in the history
  • Loading branch information
nuintun committed Feb 29, 2024
1 parent ee12b0c commit 3ea7790
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 20 deletions.
13 changes: 4 additions & 9 deletions packages/core/src/encoder/Encoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import {
appendModeInfo,
appendTerminator,
calculateBitsNeeded,
chooseBestMask,
chooseBestMaskAndMatrix,
chooseRecommendVersion,
Hints,
injectECCodewords,
isByteMode,
isHanziMode,
recommendVersion,
Segment,
SegmentBlock,
willFit
Expand All @@ -23,8 +23,6 @@ import { Encoded } from './Encoded';
import { Charset } from '/common/Charset';
import { ECLevel } from '/common/ECLevel';
import { BitArray } from '/common/BitArray';
import { buildMatrix } from './utils/matrix';
import { ByteMatrix } from '/common/ByteMatrix';
import { Version, VERSIONS } from '/common/Version';
import { encode as contentEncode, TextEncode } from '/common/encoding';
import { assertHints, assertLevel, assertVersion } from './utils/asserts';
Expand Down Expand Up @@ -106,7 +104,7 @@ export class Encoder {
let version: Version;

if (versionNumber === 'Auto') {
version = recommendVersion(segmentBlocks, ecLevel);
version = chooseRecommendVersion(segmentBlocks, ecLevel);
} else {
version = VERSIONS[versionNumber - 1];

Expand All @@ -131,11 +129,8 @@ export class Encoder {

appendTerminator(headAndDataBits, ecBlocks.numTotalDataCodewords);

const matrix = new ByteMatrix(version.size);
const codewords = injectECCodewords(headAndDataBits, ecBlocks);
const mask = chooseBestMask(matrix, codewords, version, ecLevel);

buildMatrix(matrix, codewords, version, ecLevel, mask);
const [mask, matrix] = chooseBestMaskAndMatrix(codewords, version, ecLevel);

return new Encoded(matrix, version, ecLevel, mask);
}
Expand Down
25 changes: 15 additions & 10 deletions packages/core/src/encoder/utils/encoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ export function calculateBitsNeeded(segmentBlocks: SegmentBlock[], version: Vers
return bitsNeeded;
}

export function recommendVersion(segmentBlocks: SegmentBlock[], ecLevel: ECLevel): Version {
export function chooseRecommendVersion(segmentBlocks: SegmentBlock[], ecLevel: ECLevel): Version {
// Hard part: need to know version to know how many bits length takes. But need to know how many
// bits it takes to know version. First we take a guess at version by assuming version will be
// the minimum, 1:
Expand All @@ -222,22 +222,27 @@ export function recommendVersion(segmentBlocks: SegmentBlock[], ecLevel: ECLevel
return chooseVersion(bitsNeeded, ecLevel);
}

export function chooseBestMask(matrix: ByteMatrix, bits: BitArray, version: Version, ecLevel: ECLevel): number {
let bestMask = -1;
// Lower penalty is better.
let minPenalty = Number.MAX_VALUE;

// We try all mask patterns to choose the best one.
for (let mask = 0; mask < 8; mask++) {
buildMatrix(matrix, bits, version, ecLevel, mask);
export function chooseBestMaskAndMatrix(
bits: BitArray,
version: Version,
ecLevel: ECLevel
): [mask: number, matrix: ByteMatrix] {
let bestMask = 0;
let bestMatrix = buildMatrix(bits, version, ecLevel, bestMask);
let minPenalty = calculateMaskPenalty(bestMatrix);

// We try all rest mask patterns to choose the best one.
for (let mask = 1; mask < 8; mask++) {
const matrix = buildMatrix(bits, version, ecLevel, mask);
const penalty = calculateMaskPenalty(matrix);

// Lower penalty is better.
if (penalty < minPenalty) {
bestMask = mask;
bestMatrix = matrix;
minPenalty = penalty;
}
}

return bestMask;
return [bestMask, bestMatrix];
}
6 changes: 5 additions & 1 deletion packages/core/src/encoder/utils/matrix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,12 +339,16 @@ function embedEncodingRegion(matrix: ByteMatrix, codewords: BitArray, version: V

// Build 2D matrix of QR Code from "codewords" with "ecLevel", "version" and "getMaskPattern". On
// success, store the result in "matrix".
export function buildMatrix(matrix: ByteMatrix, codewords: BitArray, version: Version, ecLevel: ECLevel, mask: number): void {
export function buildMatrix(codewords: BitArray, version: Version, ecLevel: ECLevel, mask: number): ByteMatrix {
const matrix = new ByteMatrix(version.size);

// Clear matrix
matrix.clear(-1);

// Embed function patterns
embedFunctionPatterns(matrix, version);
// Embed encoding region
embedEncodingRegion(matrix, codewords, version, ecLevel, mask);

return matrix;
}

0 comments on commit 3ea7790

Please sign in to comment.