From 7a07fdde4646357a68f691fbaee6c418242205f6 Mon Sep 17 00:00:00 2001 From: WasabiThumb Date: Tue, 9 Jul 2024 08:15:58 -0400 Subject: [PATCH 1/8] Join colinear segments in SVG --- src/renderer/impl/svg.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/renderer/impl/svg.ts b/src/renderer/impl/svg.ts index e26a941..3b31c3a 100644 --- a/src/renderer/impl/svg.ts +++ b/src/renderer/impl/svg.ts @@ -330,6 +330,7 @@ class TracerLineGroup { if (startIndex >= this.traversed.length) return null; this.traversed.set(startIndex); + let lastDirection: number = -1; let cur: TracerLine = this.lines[startIndex]; let ret: TracerLine[] = []; @@ -343,11 +344,14 @@ class TracerLineGroup { if (nextIndex === startIndex) break; this.traversed.set(nextIndex); - ret.push(cur); + if (cur[4] !== lastDirection) { + ret.push(cur); + lastDirection = cur[4]; + } cur = next; } - ret.push(cur); + if (cur[4] !== lastDirection) ret.push(cur); return ret; } From 8e34211047ff6a7451905c4358352ae8cfdfbcd4 Mon Sep 17 00:00:00 2001 From: WasabiThumb Date: Tue, 9 Jul 2024 08:27:52 -0400 Subject: [PATCH 2/8] Comment out unused code --- package.json | 2 +- src/collection/bitArray.ts | 6 ++++++ src/ec/gf.ts | 2 ++ src/lib.ts | 6 ------ src/qr/mode.ts | 8 +++++--- src/qr/version.ts | 7 ++++++- src/util/mask.ts | 2 +- 7 files changed, 21 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index d26c73f..c82b672 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "enqr", "description": "Lightweight QR encoder for the browser & node loosely based on zxing", - "version": "1.2.0", + "version": "1.3.0", "main": "dist/index.js", "types": "types/index.d.ts", "homepage": "https://github.com/WasabiThumb/enqr", diff --git a/src/collection/bitArray.ts b/src/collection/bitArray.ts index 9f07212..e7ce4cb 100644 --- a/src/collection/bitArray.ts +++ b/src/collection/bitArray.ts @@ -86,6 +86,7 @@ export class BitArray { this.i32[i >> 5] ^= (1 << (i & 31)); } + /* getNextSet(from: number = 0): number { if (from >= this.size) return this.size; let bitsOffset = from >> 5; @@ -98,6 +99,7 @@ export class BitArray { const result = (bitsOffset * 32) + ctz32(currentBits); return Math.min(result, this.size); } + */ getNextUnset(from: number = 0): number { if (from >= this.size) return this.size; @@ -150,6 +152,7 @@ export class BitArray { this.i32.fill(0); } + /* isRange(start: number, end: number, value: boolean = true): boolean { let ret: boolean = true; this.withRange(start, end, (v, mask) => { @@ -161,6 +164,7 @@ export class BitArray { }); return ret; } + */ appendBit(bit: boolean = true): void { const s: number = this.size; @@ -189,11 +193,13 @@ export class BitArray { } } + /* clone(): BitArray { const ret = new BitArray(this.size); ret.i32.set(this.i32); return ret; } + */ copyTo(dest: Int32Array, offset: number = 0): void { const maxLen: number = dest.length - offset; diff --git a/src/ec/gf.ts b/src/ec/gf.ts index 967cab0..ee7a2ba 100644 --- a/src/ec/gf.ts +++ b/src/ec/gf.ts @@ -116,6 +116,7 @@ export class GenericGFPoly { return this.coefficients[this.coefficients.length - 1 - degree]; } + /* evaluateAt(a: number): number { if (a === 0) return this.getCoefficient(0); if (a === 1) { @@ -131,6 +132,7 @@ export class GenericGFPoly { } return result; } + */ private _assertFieldEq(other: GenericGFPoly): void { if (this.field !== other.field) throw new Error("GenericGFPolys do not have same GenericGF field"); diff --git a/src/lib.ts b/src/lib.ts index 64a61a2..393d5d7 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -1,9 +1,3 @@ export * from "./qr/encoder"; -export * from "./qr/mode"; export * from "./qr/qrcode"; -export * from "./qr/version"; -export * from "./util/string"; -export * from "./collection/bitArray"; -export * from "./collection/bitMatrix"; -export * from "./collection/ternaryMatrix"; diff --git a/src/qr/mode.ts b/src/qr/mode.ts index 6c31d2a..3ec58e2 100644 --- a/src/qr/mode.ts +++ b/src/qr/mode.ts @@ -5,26 +5,28 @@ import {Version} from "./version"; */ export enum Mode { - TERMINATOR = 0x00, + /* TERMINATOR = 0x00, */ NUMERIC = 0x01, ALPHANUMERIC = 0x02, - STRUCTURED_APPEND = 0x03, + /* STRUCTURED_APPEND = 0x03, */ BYTE = 0x04, ECI = 0x07, KANJI = 0x08, FNC1_FIRST_POSITION = 0x05, - FNC1_SECOND_POSITION = 0x09, + /* FNC1_SECOND_POSITION = 0x09, */ HANZI = 0x0D, } export namespace Mode { + /* export function forBits(bits: number): Mode { if (bits < 0x00 || (bits > 0x09 && bits !== 0x0D) || bits === 0x06) { throw new Error("Invalid mode bits: 0x" + bits.toString(16)); } return bits as unknown as Mode; } + */ function getCharacterCountBits0(mode: Mode): [number, number, number] { switch (mode) { diff --git a/src/qr/version.ts b/src/qr/version.ts index 7151fc0..a28796e 100644 --- a/src/qr/version.ts +++ b/src/qr/version.ts @@ -4,7 +4,6 @@ */ import {ErrorCorrectionLevel} from "../ec/level"; -import {BitMatrix} from "../collection/bitMatrix"; export interface ECB { readonly count: number, @@ -64,6 +63,7 @@ export class Version { return this.ecBlocks[ErrorCorrectionLevel.getOrdinal(ecLevel)]; } + /* buildFunctionPattern(): BitMatrix { const dimension: number = this.dimensionForVersion; const bitMatrix = new BitMatrix(dimension, dimension); @@ -101,11 +101,13 @@ export class Version { return bitMatrix; } + */ } export namespace Version { + /* const VERSION_DECODE_INFO: Int32Array = new Int32Array([ 0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6, 0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78, @@ -115,6 +117,7 @@ export namespace Version { 0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B, 0x2542E, 0x26A64, 0x27541, 0x28C69 ]); + */ // see buildVersions let VERSIONS: Version[] = []; @@ -124,6 +127,7 @@ export namespace Version { return VERSIONS[versionNumber - 1]; } + /* export function getProvisionalVersionForDimension(dimension: number): Version { if (dimension % 4 !== 1) { throw new Error("Dimension is not 1 mod 4"); @@ -153,6 +157,7 @@ export namespace Version { if (bestDifference <= 3) return getVersionForNumber(bestVersion); return null; } + */ // diff --git a/src/util/mask.ts b/src/util/mask.ts index 9a40ed8..26a9ddf 100644 --- a/src/util/mask.ts +++ b/src/util/mask.ts @@ -1,4 +1,4 @@ -import {TernaryMatrix, TernaryValue} from "../collection/ternaryMatrix"; +import {TernaryValue} from "../collection/ternaryMatrix"; /* * Reference: https://github.com/zxing/zxing/blob/master/core/src/main/java/com/google/zxing/qrcode/encoder/MaskUtil.java From c9831ca2cf10f67d1f9e0441c88978eb0ed16dfc Mon Sep 17 00:00:00 2001 From: WasabiThumb Date: Tue, 9 Jul 2024 09:43:56 -0400 Subject: [PATCH 3/8] Exclude large tables from UMD build --- .idea/webResources.xml | 14 +++++ package.json | 2 +- patches/README.md | 3 + patches/sbcs-data-generated.js | 13 ++++ patches/sbcs-data.js | 4 ++ src/util/string.ts | 4 +- tests/util/string.test.ts | 105 +++++++++++++++++++++++++++++++++ webpack.config.js | 12 ++++ 8 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 .idea/webResources.xml create mode 100644 patches/README.md create mode 100644 patches/sbcs-data-generated.js create mode 100644 patches/sbcs-data.js create mode 100644 tests/util/string.test.ts diff --git a/.idea/webResources.xml b/.idea/webResources.xml new file mode 100644 index 0000000..532910f --- /dev/null +++ b/.idea/webResources.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/package.json b/package.json index c82b672..ea5cdaf 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,6 @@ "dependencies": { "browser-or-node": "^3.0.0", "canvas": "^2.11.2", - "iconv-lite": "^0.6.3" + "iconv-lite": "0.6.3" } } diff --git a/patches/README.md b/patches/README.md new file mode 100644 index 0000000..ef58056 --- /dev/null +++ b/patches/README.md @@ -0,0 +1,3 @@ +Patches for certain files that cannot be outright excluded +in the Webpack build, but provides a substantial improvement to the bundle +size when replaced. diff --git a/patches/sbcs-data-generated.js b/patches/sbcs-data-generated.js new file mode 100644 index 0000000..0a38660 --- /dev/null +++ b/patches/sbcs-data-generated.js @@ -0,0 +1,13 @@ + +// Patch for iconv-lite/encodings/sbcs-data-generated.js + +module.exports = { + "iso88591": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "ascii": { + "type": "_sbcs", + "chars": "��������������������������������������������������������������������������������������������������������������������������������" + }, +}; diff --git a/patches/sbcs-data.js b/patches/sbcs-data.js new file mode 100644 index 0000000..dbdff81 --- /dev/null +++ b/patches/sbcs-data.js @@ -0,0 +1,4 @@ + +// Patch for iconv-lite/encodings/sbcs-data.js + +module.exports = {}; diff --git a/src/util/string.ts b/src/util/string.ts index d0fd15c..434b979 100644 --- a/src/util/string.ts +++ b/src/util/string.ts @@ -73,8 +73,8 @@ class NativeCharset implements Charset { * xzing/common/StringUtils */ export const Charsets = { - US_ASCII: new IconvCharset("us-ascii", "US_ASCII") as Charset, - ISO_8859_1: new IconvCharset("latin1", "ISO_8859_1") as Charset, + US_ASCII: new IconvCharset("ascii", "US_ASCII") as Charset, + ISO_8859_1: new IconvCharset("iso88591", "ISO_8859_1") as Charset, UTF_8: new NativeCharset() as Charset, UTF_16BE: new IconvCharset("utf16-be", "UTF_16BE") as Charset, UTF_16LE: new IconvCharset("utf16le", "UTF_16LE") as Charset, diff --git a/tests/util/string.test.ts b/tests/util/string.test.ts new file mode 100644 index 0000000..1c5a308 --- /dev/null +++ b/tests/util/string.test.ts @@ -0,0 +1,105 @@ +import { Test, runTests, assertEquals } from "../junit"; +import {Charset, CharsetName, Charsets, StringBuilder} from "../../src/util/string"; + +// START Test Charsets + +const TEST_STRING = `EnQR © わさび Codes 2024 😊`; + +const EXPECTED_ENCODINGS: { [k: string]: Uint8Array } = { + "US_ASCII": new Uint8Array([ + 0x45, 0x6E, 0x51, 0x52, 0x20, 0x3F, 0x20, 0x3F, 0x3F, 0x3F, 0x20, 0x43, 0x6F, 0x64, 0x65, 0x73, 0x20, 0x32, 0x30, + 0x32, 0x34, 0x20, 0x3F, 0x3F + ]), + "ISO_8859_1": new Uint8Array([ + 0x45, 0x6E, 0x51, 0x52, 0x20, 0xA9, 0x20, 0x3F, 0x3F, 0x3F, 0x20, 0x43, 0x6F, 0x64, 0x65, 0x73, 0x20, 0x32, 0x30, + 0x32, 0x34, 0x20, 0x3F, 0x3F + ]), + "UTF_8": new Uint8Array([ + 0x45, 0x6E, 0x51, 0x52, 0x20, 0xC2, 0xA9, 0x20, 0xE3, 0x82, 0x8F, 0xE3, 0x81, 0x95, 0xE3, 0x81, 0xB3, 0x20, 0x43, + 0x6F, 0x64, 0x65, 0x73, 0x20, 0x32, 0x30, 0x32, 0x34, 0x20, 0xF0, 0x9F, 0x98, 0x8A + ]), + "UTF_16BE": new Uint8Array([ + 0x00, 0x45, 0x00, 0x6E, 0x00, 0x51, 0x00, 0x52, 0x00, 0x20, 0x00, 0xA9, 0x00, 0x20, 0x30, 0x8F, 0x30, 0x55, 0x30, + 0x73, 0x00, 0x20, 0x00, 0x43, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, + 0x00, 0x32, 0x00, 0x34, 0x00, 0x20, 0xD8, 0x3D, 0xDE, 0x0A + ]), + "UTF_16LE": new Uint8Array([ + 0x45, 0x00, 0x6E, 0x00, 0x51, 0x00, 0x52, 0x00, 0x20, 0x00, 0xA9, 0x00, 0x20, 0x00, 0x8F, 0x30, 0x55, 0x30, 0x73, + 0x30, 0x20, 0x00, 0x43, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, + 0x32, 0x00, 0x34, 0x00, 0x20, 0x00, 0x3D, 0xD8, 0x0A, 0xDE + ]), + // UTF_16 intentionally missing + "SHIFT_JIS": new Uint8Array([ + 0x45, 0x6E, 0x51, 0x52, 0x20, 0x3F, 0x20, 0x82, 0xED, 0x82, 0xB3, 0x82, 0xD1, 0x20, 0x43, 0x6F, 0x64, 0x65, 0x73, + 0x20, 0x32, 0x30, 0x32, 0x34, 0x20, 0x3F + ]), + "GB2312": new Uint8Array([ + 0x45, 0x6E, 0x51, 0x52, 0x20, 0x3F, 0x20, 0xA4, 0xEF, 0xA4, 0xB5, 0xA4, 0xD3, 0x20, 0x43, 0x6F, 0x64, 0x65, 0x73, + 0x20, 0x32, 0x30, 0x32, 0x34, 0x20, 0x3F + ]), + "EUC_JP": new Uint8Array([ + 0x45, 0x6E, 0x51, 0x52, 0x20, 0x8F, 0xA2, 0xED, 0x20, 0xA4, 0xEF, 0xA4, 0xB5, 0xA4, 0xD3, 0x20, 0x43, 0x6F, 0x64, + 0x65, 0x73, 0x20, 0x32, 0x30, 0x32, 0x34, 0x20, 0x3F + ]), +}; + +function testCharset(charset: Charset) { + const { name } = charset; + const checkBOM: boolean = name === "UTF_16"; + + test(name, () => { + let encoded: Uint8Array = charset.encode(TEST_STRING); + + let expected: Uint8Array; + if (checkBOM) { + const hi: number = encoded[0]; + const lo: number = encoded[1]; + const le: boolean = (hi === 0xFF); + expect(le ? lo : hi).toEqual(0xFE); + expected = EXPECTED_ENCODINGS[le ? "UTF_16LE" : "UTF_16BE"]; + encoded = encoded.subarray(2); + } else { + expected = EXPECTED_ENCODINGS[name]; + } + + expect(expected).not.toBeUndefined(); + expect(encoded.length).toEqual(expected.length); + for (let i=0; i < encoded.length; i++) { + expect(encoded[i]).toEqual(expected[i]); + } + }); +} + +describe("Charsets", () => { + let cs: Charset; + for (let k of Object.keys(Charsets)) { + cs = Charsets[k as CharsetName]; + testCharset(cs); + } +}); + +// START Test StringBuilder + +class StringBuilderTest { + + @Test() + basic() { + const sb = new StringBuilder(); + sb.append("Test") + .appendSpace() + .append(73) + .appendNewline(); + + sb.appendString("テスト") + .appendSpace() + .appendDigit(7) + .appendDigit(3) + .appendChar(10); + + const str = sb.toString(); + const expected: string = `Test 73\nテスト 73\n`; + assertEquals(expected, str); + } + +} +runTests(StringBuilderTest); diff --git a/webpack.config.js b/webpack.config.js index 1d0e47a..27b99c2 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -25,6 +25,18 @@ module.exports = ((env) => { extensions: ['.tsx', '.ts', '.js'], fallback: { "buffer": require.resolve("buffer/") + }, + // Trick iconv-lite into excluding tables that we dont actually need for our use case + alias: { + "./tables/big5-added.json": false, + "./tables/cp949.json": false, + "./tables/cp950.json": false, + "./tables/gb18030-ranges.json": false, + "./tables/gbk-added.json": false, + "./utf7": false, + "./utf32": false, + "./sbcs-data-generated": path.resolve(__dirname, "patches/sbcs-data-generated.js"), + "./sbcs-data": path.resolve(__dirname, "patches/sbcs-data.js") } }, output: { From 23be9641fae703e0645be9fd402432838e5b3e7f Mon Sep 17 00:00:00 2001 From: WasabiThumb Date: Tue, 9 Jul 2024 09:44:44 -0400 Subject: [PATCH 4/8] Add patches dir to npmignore --- .npmignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.npmignore b/.npmignore index d9bc18c..b66aea6 100644 --- a/.npmignore +++ b/.npmignore @@ -7,3 +7,4 @@ tsconfig.json webpack.config.js tsconfig.webpack.json .github +patches From 2f290ddc957fe19dc953aa8cea843dd461c0b284 Mon Sep 17 00:00:00 2001 From: WasabiThumb Date: Tue, 9 Jul 2024 09:45:46 -0400 Subject: [PATCH 5/8] Update package-lock.json --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a8e51a3..eaa870e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,17 @@ { "name": "enqr", - "version": "1.0.0", + "version": "1.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "enqr", - "version": "1.0.0", + "version": "1.3.0", "license": "Apache-2.0", "dependencies": { "browser-or-node": "^3.0.0", "canvas": "^2.11.2", - "iconv-lite": "^0.6.3" + "iconv-lite": "0.6.3" }, "devDependencies": { "@types/jest": "^29.5.12", From 048de62f571bf70c1fa4363a4d3aeaef3ce01633 Mon Sep 17 00:00:00 2001 From: WasabiThumb Date: Tue, 9 Jul 2024 09:53:53 -0400 Subject: [PATCH 6/8] Add missing license info --- LICENSE.txt | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/index.ts | 18 ++++++ 2 files changed, 195 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..f433b1a --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/src/index.ts b/src/index.ts index 6f3ee8b..cf0c6ac 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,21 @@ +/* + + Copyright 2024 Wasabi Codes + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + import * as Lib from "./lib"; // From 672870cd3c68b5401473d8c7a67f81a2ae1dddc3 Mon Sep 17 00:00:00 2001 From: WasabiThumb Date: Tue, 9 Jul 2024 11:27:09 -0400 Subject: [PATCH 7/8] Reduce size of constant data --- src/collection/bitMatrix.ts | 15 +- src/qr/version.ts | 374 +++++------------------------------- src/util/matrix.ts | 104 +++++----- 3 files changed, 97 insertions(+), 396 deletions(-) diff --git a/src/collection/bitMatrix.ts b/src/collection/bitMatrix.ts index 07431e5..bf010d1 100644 --- a/src/collection/bitMatrix.ts +++ b/src/collection/bitMatrix.ts @@ -7,11 +7,16 @@ export class BitMatrix { private static ACCESS_HINT_PRIVATE = Symbol(); - static of(array: number[][]): BitMatrix { - if (array.length < 1) return new BitMatrix(0, 0); - const ret = new BitMatrix(array[0].length, array.length); - for (let y=0; y < array.length; y++) { - ret.setRow(y, BitArray.of(array[y])); + /** + * For internal usage. Creates a BitMatrix from the specified bits with a width of at most 8 + */ + static raw(width: number, ...rows: number[]): BitMatrix { + const height: number = rows.length; + const row = new BitArray(width); + const ret = new BitMatrix(width, height); + for (let i=0; i < height; i++) { + row.setBulk(0, rows[i]); + ret.setRow(i, row); } return ret; } diff --git a/src/qr/version.ts b/src/qr/version.ts index a28796e..37bdeee 100644 --- a/src/qr/version.ts +++ b/src/qr/version.ts @@ -4,6 +4,7 @@ */ import {ErrorCorrectionLevel} from "../ec/level"; +import {Buffer} from "safer-buffer"; export interface ECB { readonly count: number, @@ -39,7 +40,7 @@ export class Version { readonly versionNumber: number; readonly alignmentPatternCenters: number[]; - private readonly ecBlocks: ECBlocks[]; + readonly ecBlocks: ECBlocks[]; readonly totalCodewords: number; constructor(versionNumber: number, alignmentPatternCenters: number[], ...ecBlocks: ECBlocks[]) { this.versionNumber = versionNumber; @@ -162,336 +163,47 @@ export namespace Version { // function buildVersions(): Version[] { - return [ - new Version(1, [], - new ECBlocks(7, ECB(1, 19)), - new ECBlocks(10, ECB(1, 16)), - new ECBlocks(13, ECB(1, 13)), - new ECBlocks(17, ECB(1, 9))), - new Version(2, [6, 18], - new ECBlocks(10, ECB(1, 34)), - new ECBlocks(16, ECB(1, 28)), - new ECBlocks(22, ECB(1, 22)), - new ECBlocks(28, ECB(1, 16))), - new Version(3, [6, 22], - new ECBlocks(15, ECB(1, 55)), - new ECBlocks(26, ECB(1, 44)), - new ECBlocks(18, ECB(2, 17)), - new ECBlocks(22, ECB(2, 13))), - new Version(4, [6, 26], - new ECBlocks(20, ECB(1, 80)), - new ECBlocks(18, ECB(2, 32)), - new ECBlocks(26, ECB(2, 24)), - new ECBlocks(16, ECB(4, 9))), - new Version(5, [6, 30], - new ECBlocks(26, ECB(1, 108)), - new ECBlocks(24, ECB(2, 43)), - new ECBlocks(18, ECB(2, 15), - ECB(2, 16)), - new ECBlocks(22, ECB(2, 11), - ECB(2, 12))), - new Version(6, [6, 34], - new ECBlocks(18, ECB(2, 68)), - new ECBlocks(16, ECB(4, 27)), - new ECBlocks(24, ECB(4, 19)), - new ECBlocks(28, ECB(4, 15))), - new Version(7, [6, 22, 38], - new ECBlocks(20, ECB(2, 78)), - new ECBlocks(18, ECB(4, 31)), - new ECBlocks(18, ECB(2, 14), - ECB(4, 15)), - new ECBlocks(26, ECB(4, 13), - ECB(1, 14))), - new Version(8, [6, 24, 42], - new ECBlocks(24, ECB(2, 97)), - new ECBlocks(22, ECB(2, 38), - ECB(2, 39)), - new ECBlocks(22, ECB(4, 18), - ECB(2, 19)), - new ECBlocks(26, ECB(4, 14), - ECB(2, 15))), - new Version(9, [6, 26, 46], - new ECBlocks(30, ECB(2, 116)), - new ECBlocks(22, ECB(3, 36), - ECB(2, 37)), - new ECBlocks(20, ECB(4, 16), - ECB(4, 17)), - new ECBlocks(24, ECB(4, 12), - ECB(4, 13))), - new Version(10, [6, 28, 50], - new ECBlocks(18, ECB(2, 68), - ECB(2, 69)), - new ECBlocks(26, ECB(4, 43), - ECB(1, 44)), - new ECBlocks(24, ECB(6, 19), - ECB(2, 20)), - new ECBlocks(28, ECB(6, 15), - ECB(2, 16))), - new Version(11, [6, 30, 54], - new ECBlocks(20, ECB(4, 81)), - new ECBlocks(30, ECB(1, 50), - ECB(4, 51)), - new ECBlocks(28, ECB(4, 22), - ECB(4, 23)), - new ECBlocks(24, ECB(3, 12), - ECB(8, 13))), - new Version(12, [6, 32, 58], - new ECBlocks(24, ECB(2, 92), - ECB(2, 93)), - new ECBlocks(22, ECB(6, 36), - ECB(2, 37)), - new ECBlocks(26, ECB(4, 20), - ECB(6, 21)), - new ECBlocks(28, ECB(7, 14), - ECB(4, 15))), - new Version(13, [6, 34, 62], - new ECBlocks(26, ECB(4, 107)), - new ECBlocks(22, ECB(8, 37), - ECB(1, 38)), - new ECBlocks(24, ECB(8, 20), - ECB(4, 21)), - new ECBlocks(22, ECB(12, 11), - ECB(4, 12))), - new Version(14, [6, 26, 46, 66], - new ECBlocks(30, ECB(3, 115), - ECB(1, 116)), - new ECBlocks(24, ECB(4, 40), - ECB(5, 41)), - new ECBlocks(20, ECB(11, 16), - ECB(5, 17)), - new ECBlocks(24, ECB(11, 12), - ECB(5, 13))), - new Version(15, [6, 26, 48, 70], - new ECBlocks(22, ECB(5, 87), - ECB(1, 88)), - new ECBlocks(24, ECB(5, 41), - ECB(5, 42)), - new ECBlocks(30, ECB(5, 24), - ECB(7, 25)), - new ECBlocks(24, ECB(11, 12), - ECB(7, 13))), - new Version(16, [6, 26, 50, 74], - new ECBlocks(24, ECB(5, 98), - ECB(1, 99)), - new ECBlocks(28, ECB(7, 45), - ECB(3, 46)), - new ECBlocks(24, ECB(15, 19), - ECB(2, 20)), - new ECBlocks(30, ECB(3, 15), - ECB(13, 16))), - new Version(17, [6, 30, 54, 78], - new ECBlocks(28, ECB(1, 107), - ECB(5, 108)), - new ECBlocks(28, ECB(10, 46), - ECB(1, 47)), - new ECBlocks(28, ECB(1, 22), - ECB(15, 23)), - new ECBlocks(28, ECB(2, 14), - ECB(17, 15))), - new Version(18, [6, 30, 56, 82], - new ECBlocks(30, ECB(5, 120), - ECB(1, 121)), - new ECBlocks(26, ECB(9, 43), - ECB(4, 44)), - new ECBlocks(28, ECB(17, 22), - ECB(1, 23)), - new ECBlocks(28, ECB(2, 14), - ECB(19, 15))), - new Version(19, [6, 30, 58, 86], - new ECBlocks(28, ECB(3, 113), - ECB(4, 114)), - new ECBlocks(26, ECB(3, 44), - ECB(11, 45)), - new ECBlocks(26, ECB(17, 21), - ECB(4, 22)), - new ECBlocks(26, ECB(9, 13), - ECB(16, 14))), - new Version(20, [6, 34, 62, 90], - new ECBlocks(28, ECB(3, 107), - ECB(5, 108)), - new ECBlocks(26, ECB(3, 41), - ECB(13, 42)), - new ECBlocks(30, ECB(15, 24), - ECB(5, 25)), - new ECBlocks(28, ECB(15, 15), - ECB(10, 16))), - new Version(21, [6, 28, 50, 72, 94], - new ECBlocks(28, ECB(4, 116), - ECB(4, 117)), - new ECBlocks(26, ECB(17, 42)), - new ECBlocks(28, ECB(17, 22), - ECB(6, 23)), - new ECBlocks(30, ECB(19, 16), - ECB(6, 17))), - new Version(22, [6, 26, 50, 74, 98], - new ECBlocks(28, ECB(2, 111), - ECB(7, 112)), - new ECBlocks(28, ECB(17, 46)), - new ECBlocks(30, ECB(7, 24), - ECB(16, 25)), - new ECBlocks(24, ECB(34, 13))), - new Version(23, [6, 30, 54, 78, 102], - new ECBlocks(30, ECB(4, 121), - ECB(5, 122)), - new ECBlocks(28, ECB(4, 47), - ECB(14, 48)), - new ECBlocks(30, ECB(11, 24), - ECB(14, 25)), - new ECBlocks(30, ECB(16, 15), - ECB(14, 16))), - new Version(24, [6, 28, 54, 80, 106], - new ECBlocks(30, ECB(6, 117), - ECB(4, 118)), - new ECBlocks(28, ECB(6, 45), - ECB(14, 46)), - new ECBlocks(30, ECB(11, 24), - ECB(16, 25)), - new ECBlocks(30, ECB(30, 16), - ECB(2, 17))), - new Version(25, [6, 32, 58, 84, 110], - new ECBlocks(26, ECB(8, 106), - ECB(4, 107)), - new ECBlocks(28, ECB(8, 47), - ECB(13, 48)), - new ECBlocks(30, ECB(7, 24), - ECB(22, 25)), - new ECBlocks(30, ECB(22, 15), - ECB(13, 16))), - new Version(26, [6, 30, 58, 86, 114], - new ECBlocks(28, ECB(10, 114), - ECB(2, 115)), - new ECBlocks(28, ECB(19, 46), - ECB(4, 47)), - new ECBlocks(28, ECB(28, 22), - ECB(6, 23)), - new ECBlocks(30, ECB(33, 16), - ECB(4, 17))), - new Version(27, [6, 34, 62, 90, 118], - new ECBlocks(30, ECB(8, 122), - ECB(4, 123)), - new ECBlocks(28, ECB(22, 45), - ECB(3, 46)), - new ECBlocks(30, ECB(8, 23), - ECB(26, 24)), - new ECBlocks(30, ECB(12, 15), - ECB(28, 16))), - new Version(28, [6, 26, 50, 74, 98, 122], - new ECBlocks(30, ECB(3, 117), - ECB(10, 118)), - new ECBlocks(28, ECB(3, 45), - ECB(23, 46)), - new ECBlocks(30, ECB(4, 24), - ECB(31, 25)), - new ECBlocks(30, ECB(11, 15), - ECB(31, 16))), - new Version(29, [6, 30, 54, 78, 102, 126], - new ECBlocks(30, ECB(7, 116), - ECB(7, 117)), - new ECBlocks(28, ECB(21, 45), - ECB(7, 46)), - new ECBlocks(30, ECB(1, 23), - ECB(37, 24)), - new ECBlocks(30, ECB(19, 15), - ECB(26, 16))), - new Version(30, [6, 26, 52, 78, 104, 130], - new ECBlocks(30, ECB(5, 115), - ECB(10, 116)), - new ECBlocks(28, ECB(19, 47), - ECB(10, 48)), - new ECBlocks(30, ECB(15, 24), - ECB(25, 25)), - new ECBlocks(30, ECB(23, 15), - ECB(25, 16))), - new Version(31, [6, 30, 56, 82, 108, 134], - new ECBlocks(30, ECB(13, 115), - ECB(3, 116)), - new ECBlocks(28, ECB(2, 46), - ECB(29, 47)), - new ECBlocks(30, ECB(42, 24), - ECB(1, 25)), - new ECBlocks(30, ECB(23, 15), - ECB(28, 16))), - new Version(32, [6, 34, 60, 86, 112, 138], - new ECBlocks(30, ECB(17, 115)), - new ECBlocks(28, ECB(10, 46), - ECB(23, 47)), - new ECBlocks(30, ECB(10, 24), - ECB(35, 25)), - new ECBlocks(30, ECB(19, 15), - ECB(35, 16))), - new Version(33, [6, 30, 58, 86, 114, 142], - new ECBlocks(30, ECB(17, 115), - ECB(1, 116)), - new ECBlocks(28, ECB(14, 46), - ECB(21, 47)), - new ECBlocks(30, ECB(29, 24), - ECB(19, 25)), - new ECBlocks(30, ECB(11, 15), - ECB(46, 16))), - new Version(34, [6, 34, 62, 90, 118, 146], - new ECBlocks(30, ECB(13, 115), - ECB(6, 116)), - new ECBlocks(28, ECB(14, 46), - ECB(23, 47)), - new ECBlocks(30, ECB(44, 24), - ECB(7, 25)), - new ECBlocks(30, ECB(59, 16), - ECB(1, 17))), - new Version(35, [6, 30, 54, 78, 102, 126, 150], - new ECBlocks(30, ECB(12, 121), - ECB(7, 122)), - new ECBlocks(28, ECB(12, 47), - ECB(26, 48)), - new ECBlocks(30, ECB(39, 24), - ECB(14, 25)), - new ECBlocks(30, ECB(22, 15), - ECB(41, 16))), - new Version(36, [6, 24, 50, 76, 102, 128, 154], - new ECBlocks(30, ECB(6, 121), - ECB(14, 122)), - new ECBlocks(28, ECB(6, 47), - ECB(34, 48)), - new ECBlocks(30, ECB(46, 24), - ECB(10, 25)), - new ECBlocks(30, ECB(2, 15), - ECB(64, 16))), - new Version(37, [6, 28, 54, 80, 106, 132, 158], - new ECBlocks(30, ECB(17, 122), - ECB(4, 123)), - new ECBlocks(28, ECB(29, 46), - ECB(14, 47)), - new ECBlocks(30, ECB(49, 24), - ECB(10, 25)), - new ECBlocks(30, ECB(24, 15), - ECB(46, 16))), - new Version(38, [6, 32, 58, 84, 110, 136, 162], - new ECBlocks(30, ECB(4, 122), - ECB(18, 123)), - new ECBlocks(28, ECB(13, 46), - ECB(32, 47)), - new ECBlocks(30, ECB(48, 24), - ECB(14, 25)), - new ECBlocks(30, ECB(42, 15), - ECB(32, 16))), - new Version(39, [6, 26, 54, 82, 110, 138, 166], - new ECBlocks(30, ECB(20, 117), - ECB(4, 118)), - new ECBlocks(28, ECB(40, 47), - ECB(7, 48)), - new ECBlocks(30, ECB(43, 24), - ECB(22, 25)), - new ECBlocks(30, ECB(10, 15), - ECB(67, 16))), - new Version(40, [6, 30, 58, 86, 114, 142, 170], - new ECBlocks(30, ECB(19, 118), - ECB(6, 119)), - new ECBlocks(28, ECB(18, 47), - ECB(31, 48)), - new ECBlocks(30, ECB(34, 24), - ECB(34, 25)), - new ECBlocks(30, ECB(20, 15), - ECB(61, 16))) - ]; + const CWPB_MAP: number[] = [7,10,13,15,16,17,18,20,22,24,26,28,30]; + const dat = `AAElARMBEAENAQkCBhSLASIBHAEWARACCDpoATcBLAIRAg0CCnakAVACIAIYBAliDKloAWwCKwIPAhACCwIMAg5kmwJEBBsEEwQPYwgQdmoCTgQfAg4EDwQNAQ5zCRKYigJhAiYCJwQSAhMEDgIPcwoUyHkCdAMkAiUEEAQRBAwEDXsLFmqbAkQCRQQrASwGEwIUBg8CEHMMGHy5BFEBMgQzBBYEFwMMCA17DRqYqwJcAl0GJAIlBBQGFQcOBA9zDhyomARrCCUBJggUBBUMCwQMfAoUHsl5A3MBdAQoBSkLEAURCwwFDXwKFSCJyQVXAVgFKQUqBRgHGQsMBw18ChYim5wFYgFjBy0DLg8TAhQDDw0QfAwYJLu7AWsFbAouAS8BFg8XAg4RD3wMGSbKuwV4AXkJKwQsERYBFwIOEw98DBoouqoDcQRyAywLLREVBBYJDRAOfA4cKrrLA2sFbAMpDSoPGAUZDw8KEG0LFiEsurwEdAR1ESoRFgYXExAGES0KFiIuu8kCbwdwES4HGBAZIg19DBgkMMvMBHkFegQvDjALGA4ZEA8OEH0LGCUyy8wGdQR2Bi0OLgsYEBkeEAIRfQ0aJzSrzAhqBGsILw0wBxgWGRYPDRB9DBooNru8CnICcxMuBC8cFgYXIRAEEX0OHCo4y8wIegR7Fi0DLggXGhgMDxwQfgoWIi46y8wDdQp2Ay0XLgQYHxkLDx8QfgwYJDA8y8wHdAd1FS0HLgEXJRgTDxoQfgoXJDE+y8wFcwp0Ey8KMA8YGRkXDxkQfgwZJjNAy8wNcwN0Ai4dLyoYARkXDxwQdg4bKDVCy8wRcwouFy8KGCMZEw8jEH4MGig2RMvMEXMBdA4uFS8dGBMZCw8uEH4OHCo4RsvMDXMGdA4uFy8sGAcZOxABEX8MGCQwPEjLzAx5B3oMLxowJxgOGRYPKRB/CRYjMD1Ky8wGeQ56Bi8iMC4YChkCD0AQfwsYJTI/TMvMEXoEex0uDi8xGAoZGA8uEH8NGic0QU7LzAR6EnsNLiAvMBgOGSoPIBB/ChgmNEJQy8wUdQR2KC8HMCsYFhkKD0MQfwwaKDZEUsvME3YGdxIvHzAiGCIZFA89EA==`; + const bin: Uint8Array = Buffer.from(dat, "base64"); + + let i = 0; + let version: number = 0; + const versions: Version[] = new Array(40); + + while (i < bin.length && (version++) < 40) { + let flag: number = bin[i++]; + const alignmentPatternCentersLength: number = flag & 7; + flag >>= 3; + + const alignmentPatternCenters: number[] = new Array(alignmentPatternCentersLength); + if (alignmentPatternCentersLength !== 0) alignmentPatternCenters[0] = 6; + for (let z=1; z < alignmentPatternCentersLength; z++) + alignmentPatternCenters[z] = (bin[i++] << 1) + 6; + + const codewordsPerBlockHi = bin[i++]; + const codewordsPerBlockLo = bin[i++]; + + const ecBlocks: ECBlocks[] = new Array(4); + for (let q=0; q < 4; q++) { + const count: number = (flag & 1) ? 2 : 1; + flag >>= 1; + + const ecbs: ECB[] = new Array(count); + let tmp: number; + for (let z=0; z < count; z++) { + tmp = bin[i++]; + ecbs[z] = ECB(tmp, bin[i++]); + } + + let cwpb = (q < 2) ? codewordsPerBlockHi : codewordsPerBlockLo; + ecBlocks[q] = new ECBlocks(CWPB_MAP[(q & 1) ? (cwpb & 0xF) : (cwpb >> 4)], ...ecbs); + } + + versions[version - 1] = new Version(version, alignmentPatternCenters, ...ecBlocks); + } + + return versions; } VERSIONS = buildVersions(); diff --git a/src/util/matrix.ts b/src/util/matrix.ts index 252b727..156f242 100644 --- a/src/util/matrix.ts +++ b/src/util/matrix.ts @@ -12,65 +12,50 @@ import {MaskUtil} from "./mask"; export namespace MatrixUtil { - export const POSITION_DETECTION_PATTERN: BitMatrix = BitMatrix.of([ - [1, 1, 1, 1, 1, 1, 1], - [1, 0, 0, 0, 0, 0, 1], - [1, 0, 1, 1, 1, 0, 1], - [1, 0, 1, 1, 1, 0, 1], - [1, 0, 1, 1, 1, 0, 1], - [1, 0, 0, 0, 0, 0, 1], - [1, 1, 1, 1, 1, 1, 1], - ]); - - export const POSITION_ADJUSTMENT_PATTERN: BitMatrix = BitMatrix.of([ - [ 1, 1, 1, 1, 1 ], - [ 1, 0, 0, 0, 1 ], - [ 1, 0, 1, 0, 1 ], - [ 1, 0, 0, 0, 1 ], - [ 1, 1, 1, 1, 1 ], - ]); + export const POSITION_DETECTION_PATTERN: BitMatrix = BitMatrix.raw(7,127,65,93,93,93,65,127); + + export const POSITION_ADJUSTMENT_PATTERN: BitMatrix = BitMatrix.raw(5,31,17,21,17,31); export const POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE: number[][] = [ - [-1, -1, -1, -1, -1, -1, -1], // Version 1 - [ 6, 18, -1, -1, -1, -1, -1], // Version 2 - [ 6, 22, -1, -1, -1, -1, -1], // Version 3 - [ 6, 26, -1, -1, -1, -1, -1], // Version 4 - [ 6, 30, -1, -1, -1, -1, -1], // Version 5 - [ 6, 34, -1, -1, -1, -1, -1], // Version 6 - [ 6, 22, 38, -1, -1, -1, -1], // Version 7 - [ 6, 24, 42, -1, -1, -1, -1], // Version 8 - [ 6, 26, 46, -1, -1, -1, -1], // Version 9 - [ 6, 28, 50, -1, -1, -1, -1], // Version 10 - [ 6, 30, 54, -1, -1, -1, -1], // Version 11 - [ 6, 32, 58, -1, -1, -1, -1], // Version 12 - [ 6, 34, 62, -1, -1, -1, -1], // Version 13 - [ 6, 26, 46, 66, -1, -1, -1], // Version 14 - [ 6, 26, 48, 70, -1, -1, -1], // Version 15 - [ 6, 26, 50, 74, -1, -1, -1], // Version 16 - [ 6, 30, 54, 78, -1, -1, -1], // Version 17 - [ 6, 30, 56, 82, -1, -1, -1], // Version 18 - [ 6, 30, 58, 86, -1, -1, -1], // Version 19 - [ 6, 34, 62, 90, -1, -1, -1], // Version 20 - [ 6, 28, 50, 72, 94, -1, -1], // Version 21 - [ 6, 26, 50, 74, 98, -1, -1], // Version 22 - [ 6, 30, 54, 78, 102, -1, -1], // Version 23 - [ 6, 28, 54, 80, 106, -1, -1], // Version 24 - [ 6, 32, 58, 84, 110, -1, -1], // Version 25 - [ 6, 30, 58, 86, 114, -1, -1], // Version 26 - [ 6, 34, 62, 90, 118, -1, -1], // Version 27 - [ 6, 26, 50, 74, 98, 122, -1], // Version 28 - [ 6, 30, 54, 78, 102, 126, -1], // Version 29 - [ 6, 26, 52, 78, 104, 130, -1], // Version 30 - [ 6, 30, 56, 82, 108, 134, -1], // Version 31 - [ 6, 34, 60, 86, 112, 138, -1], // Version 32 - [ 6, 30, 58, 86, 114, 142, -1], // Version 33 - [ 6, 34, 62, 90, 118, 146, -1], // Version 34 - [ 6, 30, 54, 78, 102, 126, 150], // Version 35 - [ 6, 24, 50, 76, 102, 128, 154], // Version 36 - [ 6, 28, 54, 80, 106, 132, 158], // Version 37 - [ 6, 32, 58, 84, 110, 136, 162], // Version 38 - [ 6, 26, 54, 82, 110, 138, 166], // Version 39 - [ 6, 30, 58, 86, 114, 142, 170], // Version 40 + [ 6, 18 ], // Version 2 + [ 6, 22 ], // Version 3 + [ 6, 26 ], // Version 4 + [ 6, 30 ], // Version 5 + [ 6, 34 ], // Version 6 + [ 6, 22, 38 ], // Version 7 + [ 6, 24, 42 ], // Version 8 + [ 6, 26, 46 ], // Version 9 + [ 6, 28, 50 ], // Version 10 + [ 6, 30, 54 ], // Version 11 + [ 6, 32, 58 ], // Version 12 + [ 6, 34, 62 ], // Version 13 + [ 6, 26, 46, 66 ], // Version 14 + [ 6, 26, 48, 70 ], // Version 15 + [ 6, 26, 50, 74 ], // Version 16 + [ 6, 30, 54, 78 ], // Version 17 + [ 6, 30, 56, 82 ], // Version 18 + [ 6, 30, 58, 86 ], // Version 19 + [ 6, 34, 62, 90 ], // Version 20 + [ 6, 28, 50, 72, 94 ], // Version 21 + [ 6, 26, 50, 74, 98 ], // Version 22 + [ 6, 30, 54, 78, 102 ], // Version 23 + [ 6, 28, 54, 80, 106 ], // Version 24 + [ 6, 32, 58, 84, 110 ], // Version 25 + [ 6, 30, 58, 86, 114 ], // Version 26 + [ 6, 34, 62, 90, 118 ], // Version 27 + [ 6, 26, 50, 74, 98, 122 ], // Version 28 + [ 6, 30, 54, 78, 102, 126 ], // Version 29 + [ 6, 26, 52, 78, 104, 130 ], // Version 30 + [ 6, 30, 56, 82, 108, 134 ], // Version 31 + [ 6, 34, 60, 86, 112, 138 ], // Version 32 + [ 6, 30, 58, 86, 114, 142 ], // Version 33 + [ 6, 34, 62, 90, 118, 146 ], // Version 34 + [ 6, 30, 54, 78, 102, 126, 150 ], // Version 35 + [ 6, 24, 50, 76, 102, 128, 154 ], // Version 36 + [ 6, 28, 54, 80, 106, 132, 158 ], // Version 37 + [ 6, 32, 58, 84, 110, 136, 162 ], // Version 38 + [ 6, 26, 54, 82, 110, 138, 166 ], // Version 39 + [ 6, 30, 58, 86, 114, 142, 170 ], // Version 40 ]; export const TYPE_INFO_COORDINATES: [ number, number ][] = [ @@ -265,12 +250,11 @@ export namespace MatrixUtil { function maybeEmbedPositionAdjustmentPatterns(version: Version, matrix: TernaryMatrix): void { if (version.versionNumber < 2) return; - const index: number = version.versionNumber - 1; + const index: number = version.versionNumber - 2; const coordinates: number[] = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index]; for (let y of coordinates) { - if (y < 0) continue; for (let x of coordinates) { - if (x >= 0 && matrix.get(x, y) === -1) { + if (matrix.get(x, y) === -1) { embedPositionAdjustmentPattern(x - 2, y - 2, matrix); } } From 3babe1e86fd778687b7a4021ee8f706a49318d3b Mon Sep 17 00:00:00 2001 From: WasabiThumb Date: Tue, 9 Jul 2024 11:38:54 -0400 Subject: [PATCH 8/8] Update README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e382085..24b7ccf 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # EnQR -A lightweight QR encoder for the browser & node loosely based on [zxing](https://github.com/zxing/zxing). +A lightweight QR encoder for the browser & node loosely based on [zxing](https://github.com/zxing/zxing). The browser bundle is about 200KB (compare to [3.6MB](https://www.npmjs.com/package/qreator?activeTab=readme)). + This is strictly a QR encoder & renderer, future updates should consist mainly of bug fixes. [Live Demo](https://jsfiddle.net/5rept9nf/5/) | [GitHub](https://github.com/WasabiThumb/enqr/) | [NPM](https://www.npmjs.com/package/enqr)