();
- // Enum name is a Java encoding valid for java.lang and java.io
- // TYPESCRIPTPORT: changed the main label for ISO as the TextEncoder did not recognized them in the form from java
- // (eg ISO8859_1 must be ISO88591 or ISO8859-1 or ISO-8859-1)
- // later on: well, except 16 wich does not work with ISO885916 so used ISO-8859-1 form for default
- public static readonly Cp437 = new CharacterSetECI(
- CharacterSetValueIdentifiers.Cp437, Int32Array.from([0, 2]), 'Cp437');
+ // Enum name is a Java encoding valid for java.lang and java.io
+ // TYPESCRIPTPORT: changed the main label for ISO as the TextEncoder did not recognized them in the form from java
+ // (eg ISO8859_1 must be ISO88591 or ISO8859-1 or ISO-8859-1)
+ // later on: well, except 16 wich does not work with ISO885916 so used ISO-8859-1 form for default
+ public static readonly Cp437 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.Cp437, Int32Array.from([0, 2]), 'Cp437');
- public static readonly ISO8859_1 = new CharacterSetECI(
- CharacterSetValueIdentifiers.ISO8859_1, Int32Array.from([1, 3]), 'ISO-8859-1', 'ISO88591', 'ISO8859_1');
+ public static readonly ISO8859_1 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ISO8859_1, Int32Array.from([1, 3]), 'ISO-8859-1', 'ISO88591', 'ISO8859_1');
- public static readonly ISO8859_2 = new CharacterSetECI(
- CharacterSetValueIdentifiers.ISO8859_2, 4, 'ISO-8859-2', 'ISO88592', 'ISO8859_2');
+ public static readonly ISO8859_2 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ISO8859_2, 4, 'ISO-8859-2', 'ISO88592', 'ISO8859_2');
- public static readonly ISO8859_3 = new CharacterSetECI(
- CharacterSetValueIdentifiers.ISO8859_3, 5, 'ISO-8859-3', 'ISO88593', 'ISO8859_3');
+ public static readonly ISO8859_3 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ISO8859_3, 5, 'ISO-8859-3', 'ISO88593', 'ISO8859_3');
- public static readonly ISO8859_4 = new CharacterSetECI(
- CharacterSetValueIdentifiers.ISO8859_4, 6, 'ISO-8859-4', 'ISO88594', 'ISO8859_4');
+ public static readonly ISO8859_4 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ISO8859_4, 6, 'ISO-8859-4', 'ISO88594', 'ISO8859_4');
- public static readonly ISO8859_5 = new CharacterSetECI(
- CharacterSetValueIdentifiers.ISO8859_5, 7, 'ISO-8859-5', 'ISO88595', 'ISO8859_5');
+ public static readonly ISO8859_5 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ISO8859_5, 7, 'ISO-8859-5', 'ISO88595', 'ISO8859_5');
- public static readonly ISO8859_6 = new CharacterSetECI(
- CharacterSetValueIdentifiers.ISO8859_6, 8, 'ISO-8859-6', 'ISO88596', 'ISO8859_6');
+ public static readonly ISO8859_6 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ISO8859_6, 8, 'ISO-8859-6', 'ISO88596', 'ISO8859_6');
- public static readonly ISO8859_7 = new CharacterSetECI(
- CharacterSetValueIdentifiers.ISO8859_7, 9, 'ISO-8859-7', 'ISO88597', 'ISO8859_7');
+ public static readonly ISO8859_7 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ISO8859_7, 9, 'ISO-8859-7', 'ISO88597', 'ISO8859_7');
- public static readonly ISO8859_8 = new CharacterSetECI(
- CharacterSetValueIdentifiers.ISO8859_8, 10, 'ISO-8859-8', 'ISO88598', 'ISO8859_8');
+ public static readonly ISO8859_8 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ISO8859_8, 10, 'ISO-8859-8', 'ISO88598', 'ISO8859_8');
- public static readonly ISO8859_9 = new CharacterSetECI(
- CharacterSetValueIdentifiers.ISO8859_9, 11, 'ISO-8859-9', 'ISO88599', 'ISO8859_9');
+ public static readonly ISO8859_9 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ISO8859_9, 11, 'ISO-8859-9', 'ISO88599', 'ISO8859_9');
- public static readonly ISO8859_10 = new CharacterSetECI(
- CharacterSetValueIdentifiers.ISO8859_10, 12, 'ISO-8859-10', 'ISO885910', 'ISO8859_10');
+ public static readonly ISO8859_10 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ISO8859_10, 12, 'ISO-8859-10', 'ISO885910', 'ISO8859_10');
- public static readonly ISO8859_11 = new CharacterSetECI(
- CharacterSetValueIdentifiers.ISO8859_11, 13, 'ISO-8859-11', 'ISO885911', 'ISO8859_11');
+ public static readonly ISO8859_11 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ISO8859_11, 13, 'ISO-8859-11', 'ISO885911', 'ISO8859_11');
- public static readonly ISO8859_13 = new CharacterSetECI(
- CharacterSetValueIdentifiers.ISO8859_13, 15, 'ISO-8859-13', 'ISO885913', 'ISO8859_13');
+ public static readonly ISO8859_13 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ISO8859_13, 15, 'ISO-8859-13', 'ISO885913', 'ISO8859_13');
- public static readonly ISO8859_14 = new CharacterSetECI(
- CharacterSetValueIdentifiers.ISO8859_14, 16, 'ISO-8859-14', 'ISO885914', 'ISO8859_14');
+ public static readonly ISO8859_14 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ISO8859_14, 16, 'ISO-8859-14', 'ISO885914', 'ISO8859_14');
- public static readonly ISO8859_15 = new CharacterSetECI(
- CharacterSetValueIdentifiers.ISO8859_15, 17, 'ISO-8859-15', 'ISO885915', 'ISO8859_15');
+ public static readonly ISO8859_15 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ISO8859_15, 17, 'ISO-8859-15', 'ISO885915', 'ISO8859_15');
- public static readonly ISO8859_16 = new CharacterSetECI(
- CharacterSetValueIdentifiers.ISO8859_16, 18, 'ISO-8859-16', 'ISO885916', 'ISO8859_16');
+ public static readonly ISO8859_16 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ISO8859_16, 18, 'ISO-8859-16', 'ISO885916', 'ISO8859_16');
- public static readonly SJIS = new CharacterSetECI(
- CharacterSetValueIdentifiers.SJIS, 20, 'SJIS', 'Shift_JIS');
+ public static readonly SJIS = new CharacterSetECI(
+ CharacterSetValueIdentifiers.SJIS, 20, 'SJIS', 'Shift_JIS');
- public static readonly Cp1250 = new CharacterSetECI(
- CharacterSetValueIdentifiers.Cp1250, 21, 'Cp1250', 'windows-1250');
+ public static readonly Cp1250 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.Cp1250, 21, 'Cp1250', 'windows-1250');
- public static readonly Cp1251 = new CharacterSetECI(
- CharacterSetValueIdentifiers.Cp1251, 22, 'Cp1251', 'windows-1251');
+ public static readonly Cp1251 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.Cp1251, 22, 'Cp1251', 'windows-1251');
- public static readonly Cp1252 = new CharacterSetECI(
- CharacterSetValueIdentifiers.Cp1252, 23, 'Cp1252', 'windows-1252');
+ public static readonly Cp1252 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.Cp1252, 23, 'Cp1252', 'windows-1252');
- public static readonly Cp1256 = new CharacterSetECI(
- CharacterSetValueIdentifiers.Cp1256, 24, 'Cp1256', 'windows-1256');
+ public static readonly Cp1256 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.Cp1256, 24, 'Cp1256', 'windows-1256');
- public static readonly UnicodeBigUnmarked = new CharacterSetECI(
- CharacterSetValueIdentifiers.UnicodeBigUnmarked, 25, 'UnicodeBigUnmarked', 'UTF-16BE', 'UnicodeBig');
+ public static readonly UnicodeBigUnmarked = new CharacterSetECI(
+ CharacterSetValueIdentifiers.UnicodeBigUnmarked, 25, 'UnicodeBigUnmarked', 'UTF-16BE', 'UnicodeBig');
- public static readonly UTF8 = new CharacterSetECI(
- CharacterSetValueIdentifiers.UTF8, 26, 'UTF8', 'UTF-8');
+ public static readonly UTF8 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.UTF8, 26, 'UTF8', 'UTF-8');
- public static readonly ASCII = new CharacterSetECI(
- CharacterSetValueIdentifiers.ASCII, Int32Array.from([27, 170]), 'ASCII', 'US-ASCII');
+ public static readonly ASCII = new CharacterSetECI(
+ CharacterSetValueIdentifiers.ASCII, Int32Array.from([27, 170]), 'ASCII', 'US-ASCII');
- public static readonly Big5 = new CharacterSetECI(
- CharacterSetValueIdentifiers.Big5, 28, 'Big5');
+ public static readonly Big5 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.Big5, 28, 'Big5');
- public static readonly GB18030 = new CharacterSetECI(
- CharacterSetValueIdentifiers.GB18030, 29, 'GB18030', 'GB2312', 'EUC_CN', 'GBK');
+ public static readonly GB18030 = new CharacterSetECI(
+ CharacterSetValueIdentifiers.GB18030, 29, 'GB18030', 'GB2312', 'EUC_CN', 'GBK');
- public static readonly EUC_KR = new CharacterSetECI(
- CharacterSetValueIdentifiers.EUC_KR, 30, 'EUC_KR', 'EUC-KR');
+ public static readonly EUC_KR = new CharacterSetECI(
+ CharacterSetValueIdentifiers.EUC_KR, 30, 'EUC_KR', 'EUC-KR');
- public values: Int32Array;
- public otherEncodingNames: string[];
+ public values: Int32Array;
+ public otherEncodingNames: string[];
- public constructor(
- public valueIdentifier: CharacterSetValueIdentifiers,
- valuesParam: Int32Array | number,
- public name: string, ...otherEncodingNames: string[]
- ) {
+ public constructor(
+ public valueIdentifier: CharacterSetValueIdentifiers,
+ valuesParam: Int32Array | number,
+ public name: string, ...otherEncodingNames: string[]
+ ) {
- if (typeof valuesParam === 'number') {
- this.values = Int32Array.from([valuesParam]);
- } else {
- this.values = valuesParam;
- }
-
- this.otherEncodingNames = otherEncodingNames;
-
- CharacterSetECI.VALUE_IDENTIFIER_TO_ECI.set(valueIdentifier, this);
- CharacterSetECI.NAME_TO_ECI.set(name, this);
-
- const values = this.values;
-
- for (let i = 0, length = values.length; i !== length; i++) {
- const v = values[i];
- CharacterSetECI.VALUES_TO_ECI.set(v, this);
- }
- for (const otherName of otherEncodingNames) {
- CharacterSetECI.NAME_TO_ECI.set(otherName, this);
- }
+ if (typeof valuesParam === 'number') {
+ this.values = Int32Array.from([valuesParam]);
+ } else {
+ this.values = valuesParam;
}
- // CharacterSetECI(value: number /*int*/) {
- // this(new Int32Array {value})
- // }
+ this.otherEncodingNames = otherEncodingNames;
- // CharacterSetECI(value: number /*int*/, String... otherEncodingNames) {
- // this.values = new Int32Array {value}
- // this.otherEncodingNames = otherEncodingNames
- // }
+ CharacterSetECI.VALUE_IDENTIFIER_TO_ECI.set(valueIdentifier, this);
+ CharacterSetECI.NAME_TO_ECI.set(name, this);
- // CharacterSetECI(values: Int32Array, String... otherEncodingNames) {
- // this.values = values
- // this.otherEncodingNames = otherEncodingNames
- // }
+ const values = this.values;
- public getValueIdentifier(): CharacterSetValueIdentifiers/*int*/ {
- return this.valueIdentifier;
+ for (let i = 0, length = values.length; i !== length; i++) {
+ const v = values[i];
+ CharacterSetECI.VALUES_TO_ECI.set(v, this);
}
-
- public getName(): string {
- return this.name;
+ for (const otherName of otherEncodingNames) {
+ CharacterSetECI.NAME_TO_ECI.set(otherName, this);
}
+ }
+
+ // CharacterSetECI(value: number /*int */) {
+ // this(new Int32Array {value})
+ // }
+
+ // CharacterSetECI(value: number /*int */, String... otherEncodingNames) {
+ // this.values = new Int32Array {value}
+ // this.otherEncodingNames = otherEncodingNames
+ // }
+
+ // CharacterSetECI(values: Int32Array, String... otherEncodingNames) {
+ // this.values = values
+ // this.otherEncodingNames = otherEncodingNames
+ // }
+
+ public getValueIdentifier(): CharacterSetValueIdentifiers/* int */ {
+ return this.valueIdentifier;
+ }
+
+ public getName(): string {
+ return this.name;
+ }
+
+ public getValue(): number /* int */ {
+ return this.values[0];
+ }
+
+ /**
+ * @param value character set ECI value
+ * @return {@code CharacterSetECI} representing ECI of given value, or null if it is legal but
+ * unsupported
+ * @throws FormatException if ECI value is invalid
+ */
+ public static getCharacterSetECIByValue(value: number /* int */): CharacterSetECI /* throws FormatException */ {
- public getValue(): number /*int*/ {
- return this.values[0];
+ if (value < 0 || value >= 900) {
+ throw new FormatException('incorect value');
}
- /**
- * @param value character set ECI value
- * @return {@code CharacterSetECI} representing ECI of given value, or null if it is legal but
- * unsupported
- * @throws FormatException if ECI value is invalid
- */
- public static getCharacterSetECIByValue(value: number /*int*/): CharacterSetECI /*throws FormatException*/ {
-
- if (value < 0 || value >= 900) {
- throw new FormatException('incorect value');
- }
+ const characterSet = CharacterSetECI.VALUES_TO_ECI.get(value);
- const characterSet = CharacterSetECI.VALUES_TO_ECI.get(value);
-
- if (undefined === characterSet) {
- throw new FormatException('incorect value');
- }
-
- return characterSet;
+ if (undefined === characterSet) {
+ throw new FormatException('incorect value');
}
- /**
- * @param name character set ECI encoding name
- * @return CharacterSetECI representing ECI for character encoding, or null if it is legal
- * but unsupported
- */
- public static getCharacterSetECIByName(name: string): CharacterSetECI {
+ return characterSet;
+ }
- const characterSet = CharacterSetECI.NAME_TO_ECI.get(name);
+ /**
+ * @param name character set ECI encoding name
+ * @return CharacterSetECI representing ECI for character encoding, or null if it is legal
+ * but unsupported
+ */
+ public static getCharacterSetECIByName(name: string): CharacterSetECI {
- if (undefined === characterSet) {
- throw new FormatException('incorect value');
- }
+ const characterSet = CharacterSetECI.NAME_TO_ECI.get(name);
- return characterSet;
+ if (undefined === characterSet) {
+ throw new FormatException('incorect value');
}
- public equals(o: CharacterSetECI) {
+ return characterSet;
+ }
- if (!(o instanceof CharacterSetECI)) {
- return false;
- }
+ public equals(o: CharacterSetECI) {
- const other = o as CharacterSetECI;
-
- return this.getName() === other.getName();
+ if (!(o instanceof CharacterSetECI)) {
+ return false;
}
+ const other = o as CharacterSetECI;
+
+ return this.getName() === other.getName();
+ }
+
}
diff --git a/src/core/common/DecoderResult.ts b/src/core/common/DecoderResult.ts
index dadb9d59..4976d494 100644
--- a/src/core/common/DecoderResult.ts
+++ b/src/core/common/DecoderResult.ts
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common {*/
+/* namespace com.google.zxing.common { */
-/*import java.util.List;*/
+/* import java.util.List; */
/**
* Encapsulates the result of decoding a matrix of bits. This typically
@@ -27,114 +27,114 @@
*/
export default class DecoderResult {
- private numBits: number; /*int*/
- private errorsCorrected: number; /*Integer*/
- private erasures: number; /*Integer*/
- private other: any;
-
- // public constructor(rawBytes: Uint8Array,
- // text: string,
- // List byteSegments,
- // String ecLevel) {
- // this(rawBytes, text, byteSegments, ecLevel, -1, -1)
- // }
-
- public constructor(private rawBytes: Uint8Array,
- private text: string,
- private byteSegments: Uint8Array[],
- private ecLevel: string,
- private structuredAppendSequenceNumber: number /*int*/ = -1,
- private structuredAppendParity: number /*int*/ = -1) {
- this.numBits = (rawBytes === undefined || rawBytes === null) ? 0 : 8 * rawBytes.length;
- }
-
- /**
- * @return raw bytes representing the result, or {@code null} if not applicable
- */
- public getRawBytes(): Uint8Array {
- return this.rawBytes;
- }
-
- /**
- * @return how many bits of {@link #getRawBytes()} are valid; typically 8 times its length
- * @since 3.3.0
- */
- public getNumBits(): number /*int*/ {
- return this.numBits;
- }
-
- /**
- * @param numBits overrides the number of bits that are valid in {@link #getRawBytes()}
- * @since 3.3.0
- */
- public setNumBits(numBits: number /*int*/): void {
- this.numBits = numBits;
- }
-
- /**
- * @return text representation of the result
- */
- public getText(): string {
- return this.text;
- }
-
- /**
- * @return list of byte segments in the result, or {@code null} if not applicable
- */
- public getByteSegments(): Uint8Array[] {
- return this.byteSegments;
- }
-
- /**
- * @return name of error correction level used, or {@code null} if not applicable
- */
- public getECLevel(): string {
- return this.ecLevel;
- }
-
- /**
- * @return number of errors corrected, or {@code null} if not applicable
- */
- public getErrorsCorrected(): number/*Integer*/ {
- return this.errorsCorrected;
- }
-
- public setErrorsCorrected(errorsCorrected: number/*Integer*/): void {
- this.errorsCorrected = errorsCorrected;
- }
-
- /**
- * @return number of erasures corrected, or {@code null} if not applicable
- */
- public getErasures(): number/*Integer*/ {
- return this.erasures;
- }
-
- public setErasures(erasures: number/*Integer*/): void {
- this.erasures = erasures;
- }
-
- /**
- * @return arbitrary additional metadata
- */
- public getOther(): any {
- return this.other;
- }
-
- public setOther(other: any): void {
- this.other = other;
- }
-
- public hasStructuredAppend(): boolean {
- return this.structuredAppendParity >= 0 && this.structuredAppendSequenceNumber >= 0;
- }
-
- public getStructuredAppendParity(): number /*int*/ {
- return this.structuredAppendParity;
- }
-
- public getStructuredAppendSequenceNumber(): number /*int*/ {
- return this.structuredAppendSequenceNumber;
- }
+ private numBits: number; /* int */
+ private errorsCorrected: number; /* Integer */
+ private erasures: number; /* Integer */
+ private other: any;
+
+ // public constructor(rawBytes: Uint8Array,
+ // text: string,
+ // List byteSegments,
+ // String ecLevel) {
+ // this(rawBytes, text, byteSegments, ecLevel, -1, -1)
+ // }
+
+ public constructor(private rawBytes: Uint8Array,
+ private text: string,
+ private byteSegments: Uint8Array[],
+ private ecLevel: string,
+ private structuredAppendSequenceNumber: number /* int */ = -1,
+ private structuredAppendParity: number /* int */ = -1) {
+ this.numBits = (rawBytes === undefined || rawBytes === null) ? 0 : 8 * rawBytes.length;
+ }
+
+ /**
+ * @return raw bytes representing the result, or {@code null} if not applicable
+ */
+ public getRawBytes(): Uint8Array {
+ return this.rawBytes;
+ }
+
+ /**
+ * @return how many bits of {@link #getRawBytes()} are valid; typically 8 times its length
+ * @since 3.3.0
+ */
+ public getNumBits(): number /* int */ {
+ return this.numBits;
+ }
+
+ /**
+ * @param numBits overrides the number of bits that are valid in {@link #getRawBytes()}
+ * @since 3.3.0
+ */
+ public setNumBits(numBits: number /* int */): void {
+ this.numBits = numBits;
+ }
+
+ /**
+ * @return text representation of the result
+ */
+ public getText(): string {
+ return this.text;
+ }
+
+ /**
+ * @return list of byte segments in the result, or {@code null} if not applicable
+ */
+ public getByteSegments(): Uint8Array[] {
+ return this.byteSegments;
+ }
+
+ /**
+ * @return name of error correction level used, or {@code null} if not applicable
+ */
+ public getECLevel(): string {
+ return this.ecLevel;
+ }
+
+ /**
+ * @return number of errors corrected, or {@code null} if not applicable
+ */
+ public getErrorsCorrected(): number/* Integer */ {
+ return this.errorsCorrected;
+ }
+
+ public setErrorsCorrected(errorsCorrected: number/* Integer */): void {
+ this.errorsCorrected = errorsCorrected;
+ }
+
+ /**
+ * @return number of erasures corrected, or {@code null} if not applicable
+ */
+ public getErasures(): number/* Integer */ {
+ return this.erasures;
+ }
+
+ public setErasures(erasures: number/* Integer */): void {
+ this.erasures = erasures;
+ }
+
+ /**
+ * @return arbitrary additional metadata
+ */
+ public getOther(): any {
+ return this.other;
+ }
+
+ public setOther(other: any): void {
+ this.other = other;
+ }
+
+ public hasStructuredAppend(): boolean {
+ return this.structuredAppendParity >= 0 && this.structuredAppendSequenceNumber >= 0;
+ }
+
+ public getStructuredAppendParity(): number /* int */ {
+ return this.structuredAppendParity;
+ }
+
+ public getStructuredAppendSequenceNumber(): number /* int */ {
+ return this.structuredAppendSequenceNumber;
+ }
}
diff --git a/src/core/common/DefaultGridSampler.ts b/src/core/common/DefaultGridSampler.ts
index 35c8189c..06239449 100644
--- a/src/core/common/DefaultGridSampler.ts
+++ b/src/core/common/DefaultGridSampler.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common {*/
+/* namespace com.google.zxing.common { */
import GridSampler from './GridSampler';
import BitMatrix from './BitMatrix';
@@ -29,66 +29,66 @@ import { float } from '../../customTypings';
*/
export default class DefaultGridSampler extends GridSampler {
- /*@Override*/
- public sampleGrid(image: BitMatrix,
- dimensionX: number /*int*/,
- dimensionY: number /*int*/,
- p1ToX: number/*float*/, p1ToY: number/*float*/,
- p2ToX: number/*float*/, p2ToY: number/*float*/,
- p3ToX: number/*float*/, p3ToY: number/*float*/,
- p4ToX: number/*float*/, p4ToY: number/*float*/,
- p1FromX: number/*float*/, p1FromY: number/*float*/,
- p2FromX: number/*float*/, p2FromY: number/*float*/,
- p3FromX: number/*float*/, p3FromY: number/*float*/,
- p4FromX: number/*float*/, p4FromY: number/*float*/): BitMatrix /*throws NotFoundException*/ {
+ /* @Override */
+ public sampleGrid(image: BitMatrix,
+ dimensionX: number /* int */,
+ dimensionY: number /* int */,
+ p1ToX: number/* float */, p1ToY: number/* float */,
+ p2ToX: number/* float */, p2ToY: number/* float */,
+ p3ToX: number/* float */, p3ToY: number/* float */,
+ p4ToX: number/* float */, p4ToY: number/* float */,
+ p1FromX: number/* float */, p1FromY: number/* float */,
+ p2FromX: number/* float */, p2FromY: number/* float */,
+ p3FromX: number/* float */, p3FromY: number/* float */,
+ p4FromX: number/* float */, p4FromY: number/* float */): BitMatrix /* throws NotFoundException */ {
- const transform = PerspectiveTransform.quadrilateralToQuadrilateral(
- p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY,
- p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY);
+ const transform = PerspectiveTransform.quadrilateralToQuadrilateral(
+ p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY,
+ p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY);
- return this.sampleGridWithTransform(image, dimensionX, dimensionY, transform);
- }
+ return this.sampleGridWithTransform(image, dimensionX, dimensionY, transform);
+ }
- /*@Override*/
- public sampleGridWithTransform(image: BitMatrix,
- dimensionX: number /*int*/,
- dimensionY: number /*int*/,
- transform: PerspectiveTransform): BitMatrix /*throws NotFoundException*/ {
- if (dimensionX <= 0 || dimensionY <= 0) {
- throw new NotFoundException();
- }
- const bits = new BitMatrix(dimensionX, dimensionY);
- const points = new Float32Array(2 * dimensionX);
- for (let y = 0; y < dimensionY; y++) {
- const max = points.length;
- const iValue: number /*float*/ = y + 0.5;
- for (let x = 0; x < max; x += 2) {
- points[x] = (x / 2) + 0.5;
- points[x + 1] = iValue;
- }
- transform.transformPoints(points);
- // Quick check to see if points transformed to something inside the image
- // sufficient to check the endpoints
- GridSampler.checkAndNudgePoints(image, points);
- try {
- for (let x = 0; x < max; x += 2) {
- if (image.get(Math.floor(points[x]), Math.floor(points[x + 1]))) {
- // Black(-ish) pixel
- bits.set(x / 2, y);
- }
- }
- } catch (aioobe/*: ArrayIndexOutOfBoundsException*/) {
- // This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
- // transform gets "twisted" such that it maps a straight line of points to a set of points
- // whose endpoints are in bounds, but others are not. There is probably some mathematical
- // way to detect this about the transformation that I don't know yet.
- // This results in an ugly runtime exception despite our clever checks above -- can't have
- // that. We could check each point's coordinates but that feels duplicative. We settle for
- // catching and wrapping ArrayIndexOutOfBoundsException.
- throw new NotFoundException();
- }
+ /* @Override */
+ public sampleGridWithTransform(image: BitMatrix,
+ dimensionX: number /* int */,
+ dimensionY: number /* int */,
+ transform: PerspectiveTransform): BitMatrix /* throws NotFoundException */ {
+ if (dimensionX <= 0 || dimensionY <= 0) {
+ throw new NotFoundException();
+ }
+ const bits = new BitMatrix(dimensionX, dimensionY);
+ const points = new Float32Array(2 * dimensionX);
+ for (let y = 0; y < dimensionY; y++) {
+ const max = points.length;
+ const iValue: number /* float */ = y + 0.5;
+ for (let x = 0; x < max; x += 2) {
+ points[x] = (x / 2) + 0.5;
+ points[x + 1] = iValue;
+ }
+ transform.transformPoints(points);
+ // Quick check to see if points transformed to something inside the image
+ // sufficient to check the endpoints
+ GridSampler.checkAndNudgePoints(image, points);
+ try {
+ for (let x = 0; x < max; x += 2) {
+ if (image.get(Math.floor(points[x]), Math.floor(points[x + 1]))) {
+ // Black(-ish) pixel
+ bits.set(x / 2, y);
+ }
}
- return bits;
+ } catch (aioobe/* : ArrayIndexOutOfBoundsException */) {
+ // This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
+ // transform gets "twisted" such that it maps a straight line of points to a set of points
+ // whose endpoints are in bounds, but others are not. There is probably some mathematical
+ // way to detect this about the transformation that I don't know yet.
+ // This results in an ugly runtime exception despite our clever checks above -- can't have
+ // that. We could check each point's coordinates but that feels duplicative. We settle for
+ // catching and wrapping ArrayIndexOutOfBoundsException.
+ throw new NotFoundException();
+ }
}
+ return bits;
+ }
}
diff --git a/src/core/common/DetectorResult.ts b/src/core/common/DetectorResult.ts
index ceb696b1..5cda6778 100644
--- a/src/core/common/DetectorResult.ts
+++ b/src/core/common/DetectorResult.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common {*/
+/* namespace com.google.zxing.common { */
import ResultPoint from '../ResultPoint';
import BitMatrix from './BitMatrix';
@@ -28,20 +28,20 @@ import BitMatrix from './BitMatrix';
*/
export default class DetectorResult {
- private bits: BitMatrix;
- private points: Array;
+ private bits: BitMatrix;
+ private points: Array;
- public constructor(bits: BitMatrix, points: Array) {
- this.bits = bits;
- this.points = points;
- }
+ public constructor(bits: BitMatrix, points: Array) {
+ this.bits = bits;
+ this.points = points;
+ }
- public getBits(): BitMatrix {
- return this.bits;
- }
+ public getBits(): BitMatrix {
+ return this.bits;
+ }
- public getPoints(): Array {
- return this.points;
- }
+ public getPoints(): Array {
+ return this.points;
+ }
}
diff --git a/src/core/common/GlobalHistogramBinarizer.ts b/src/core/common/GlobalHistogramBinarizer.ts
index b59f0528..8339b4a4 100644
--- a/src/core/common/GlobalHistogramBinarizer.ts
+++ b/src/core/common/GlobalHistogramBinarizer.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common {*/
+/* namespace com.google.zxing.common { */
import Binarizer from '../Binarizer';
import LuminanceSource from '../LuminanceSource';
@@ -36,173 +36,173 @@ import NotFoundException from '../NotFoundException';
*/
export default class GlobalHistogramBinarizer extends Binarizer {
- private static LUMINANCE_BITS = 5;
- private static LUMINANCE_SHIFT = 8 - GlobalHistogramBinarizer.LUMINANCE_BITS;
- private static LUMINANCE_BUCKETS = 1 << GlobalHistogramBinarizer.LUMINANCE_BITS;
- private static EMPTY = Uint8ClampedArray.from([0]);
-
- private luminances: Uint8ClampedArray;
- private buckets: Int32Array;
-
- public constructor(source: LuminanceSource) {
- super(source);
- this.luminances = GlobalHistogramBinarizer.EMPTY;
- this.buckets = new Int32Array(GlobalHistogramBinarizer.LUMINANCE_BUCKETS);
+ private static LUMINANCE_BITS = 5;
+ private static LUMINANCE_SHIFT = 8 - GlobalHistogramBinarizer.LUMINANCE_BITS;
+ private static LUMINANCE_BUCKETS = 1 << GlobalHistogramBinarizer.LUMINANCE_BITS;
+ private static EMPTY = Uint8ClampedArray.from([0]);
+
+ private luminances: Uint8ClampedArray;
+ private buckets: Int32Array;
+
+ public constructor(source: LuminanceSource) {
+ super(source);
+ this.luminances = GlobalHistogramBinarizer.EMPTY;
+ this.buckets = new Int32Array(GlobalHistogramBinarizer.LUMINANCE_BUCKETS);
+ }
+
+ // Applies simple sharpening to the row data to improve performance of the 1D Readers.
+ /* @Override */
+ public getBlackRow(y: number /* int */, row: BitArray): BitArray /* throws NotFoundException */ {
+ const source = this.getLuminanceSource();
+ const width = source.getWidth();
+ if (row === undefined || row === null || row.getSize() < width) {
+ row = new BitArray(width);
+ } else {
+ row.clear();
}
- // Applies simple sharpening to the row data to improve performance of the 1D Readers.
- /*@Override*/
- public getBlackRow(y: number /*int*/, row: BitArray): BitArray /*throws NotFoundException*/ {
- const source = this.getLuminanceSource();
- const width = source.getWidth();
- if (row === undefined || row === null || row.getSize() < width) {
- row = new BitArray(width);
- } else {
- row.clear();
- }
-
- this.initArrays(width);
- const localLuminances = source.getRow(y, this.luminances);
- const localBuckets = this.buckets;
- for (let x = 0; x < width; x++) {
- localBuckets[(localLuminances[x] & 0xff) >> GlobalHistogramBinarizer.LUMINANCE_SHIFT]++;
- }
- const blackPoint = GlobalHistogramBinarizer.estimateBlackPoint(localBuckets);
-
- if (width < 3) {
- // Special case for very small images
- for (let x = 0; x < width; x++) {
- if ((localLuminances[x] & 0xff) < blackPoint) {
- row.set(x);
- }
- }
- } else {
- let left = localLuminances[0] & 0xff;
- let center = localLuminances[1] & 0xff;
- for (let x = 1; x < width - 1; x++) {
- const right = localLuminances[x + 1] & 0xff;
- // A simple -1 4 -1 box filter with a weight of 2.
- if (((center * 4) - left - right) / 2 < blackPoint) {
- row.set(x);
- }
- left = center;
- center = right;
- }
- }
- return row;
+ this.initArrays(width);
+ const localLuminances = source.getRow(y, this.luminances);
+ const localBuckets = this.buckets;
+ for (let x = 0; x < width; x++) {
+ localBuckets[(localLuminances[x] & 0xff) >> GlobalHistogramBinarizer.LUMINANCE_SHIFT]++;
}
+ const blackPoint = GlobalHistogramBinarizer.estimateBlackPoint(localBuckets);
- // Does not sharpen the data, as this call is intended to only be used by 2D Readers.
- /*@Override*/
- public getBlackMatrix(): BitMatrix /*throws NotFoundException*/ {
- const source = this.getLuminanceSource();
- const width = source.getWidth();
- const height = source.getHeight();
- const matrix = new BitMatrix(width, height);
-
- // Quickly calculates the histogram by sampling four rows from the image. This proved to be
- // more robust on the blackbox tests than sampling a diagonal as we used to do.
- this.initArrays(width);
- const localBuckets = this.buckets;
- for (let y = 1; y < 5; y++) {
- const row = Math.floor((height * y) / 5);
- const localLuminances = source.getRow(row, this.luminances);
- const right = Math.floor((width * 4) / 5);
- for (let x = Math.floor(width / 5); x < right; x++) {
- const pixel = localLuminances[x] & 0xff;
- localBuckets[pixel >> GlobalHistogramBinarizer.LUMINANCE_SHIFT]++;
- }
+ if (width < 3) {
+ // Special case for very small images
+ for (let x = 0; x < width; x++) {
+ if ((localLuminances[x] & 0xff) < blackPoint) {
+ row.set(x);
}
- const blackPoint = GlobalHistogramBinarizer.estimateBlackPoint(localBuckets);
-
- // We delay reading the entire image luminance until the black point estimation succeeds.
- // Although we end up reading four rows twice, it is consistent with our motto of
- // "fail quickly" which is necessary for continuous scanning.
- const localLuminances = source.getMatrix();
- for (let y = 0; y < height; y++) {
- const offset = y * width;
- for (let x = 0; x < width; x++) {
- const pixel = localLuminances[offset + x] & 0xff;
- if (pixel < blackPoint) {
- matrix.set(x, y);
- }
- }
+ }
+ } else {
+ let left = localLuminances[0] & 0xff;
+ let center = localLuminances[1] & 0xff;
+ for (let x = 1; x < width - 1; x++) {
+ const right = localLuminances[x + 1] & 0xff;
+ // A simple -1 4 -1 box filter with a weight of 2.
+ if (((center * 4) - left - right) / 2 < blackPoint) {
+ row.set(x);
}
-
- return matrix;
+ left = center;
+ center = right;
+ }
}
-
- /*@Override*/
- public createBinarizer(source: LuminanceSource): Binarizer {
- return new GlobalHistogramBinarizer(source);
+ return row;
+ }
+
+ // Does not sharpen the data, as this call is intended to only be used by 2D Readers.
+ /* @Override */
+ public getBlackMatrix(): BitMatrix /* throws NotFoundException */ {
+ const source = this.getLuminanceSource();
+ const width = source.getWidth();
+ const height = source.getHeight();
+ const matrix = new BitMatrix(width, height);
+
+ // Quickly calculates the histogram by sampling four rows from the image. This proved to be
+ // more robust on the blackbox tests than sampling a diagonal as we used to do.
+ this.initArrays(width);
+ const localBuckets = this.buckets;
+ for (let y = 1; y < 5; y++) {
+ const row = Math.floor((height * y) / 5);
+ const localLuminances = source.getRow(row, this.luminances);
+ const right = Math.floor((width * 4) / 5);
+ for (let x = Math.floor(width / 5); x < right; x++) {
+ const pixel = localLuminances[x] & 0xff;
+ localBuckets[pixel >> GlobalHistogramBinarizer.LUMINANCE_SHIFT]++;
+ }
}
-
- private initArrays(luminanceSize: number /*int*/): void {
- if (this.luminances.length < luminanceSize) {
- this.luminances = new Uint8ClampedArray(luminanceSize);
- }
- const buckets = this.buckets;
- for (let x = 0; x < GlobalHistogramBinarizer.LUMINANCE_BUCKETS; x++) {
- buckets[x] = 0;
+ const blackPoint = GlobalHistogramBinarizer.estimateBlackPoint(localBuckets);
+
+ // We delay reading the entire image luminance until the black point estimation succeeds.
+ // Although we end up reading four rows twice, it is consistent with our motto of
+ // "fail quickly" which is necessary for continuous scanning.
+ const localLuminances = source.getMatrix();
+ for (let y = 0; y < height; y++) {
+ const offset = y * width;
+ for (let x = 0; x < width; x++) {
+ const pixel = localLuminances[offset + x] & 0xff;
+ if (pixel < blackPoint) {
+ matrix.set(x, y);
}
+ }
}
- private static estimateBlackPoint(buckets: Int32Array): number /*int*/ /*throws NotFoundException*/ {
- // Find the tallest peak in the histogram.
- const numBuckets = buckets.length;
- let maxBucketCount = 0;
- let firstPeak = 0;
- let firstPeakSize = 0;
- for (let x = 0; x < numBuckets; x++) {
- if (buckets[x] > firstPeakSize) {
- firstPeak = x;
- firstPeakSize = buckets[x];
- }
- if (buckets[x] > maxBucketCount) {
- maxBucketCount = buckets[x];
- }
- }
+ return matrix;
+ }
- // Find the second-tallest peak which is somewhat far from the tallest peak.
- let secondPeak = 0;
- let secondPeakScore = 0;
-
- for (let x = 0; x < numBuckets; x++) {
- const distanceToBiggest = x - firstPeak;
- // Encourage more distant second peaks by multiplying by square of distance.
- const score = buckets[x] * distanceToBiggest * distanceToBiggest;
- if (score > secondPeakScore) {
- secondPeak = x;
- secondPeakScore = score;
- }
- }
+ /* @Override */
+ public createBinarizer(source: LuminanceSource): Binarizer {
+ return new GlobalHistogramBinarizer(source);
+ }
- // Make sure firstPeak corresponds to the black peak.
- if (firstPeak > secondPeak) {
- const temp = firstPeak;
- firstPeak = secondPeak;
- secondPeak = temp;
- }
+ private initArrays(luminanceSize: number /* int */): void {
+ if (this.luminances.length < luminanceSize) {
+ this.luminances = new Uint8ClampedArray(luminanceSize);
+ }
+ const buckets = this.buckets;
+ for (let x = 0; x < GlobalHistogramBinarizer.LUMINANCE_BUCKETS; x++) {
+ buckets[x] = 0;
+ }
+ }
+
+ private static estimateBlackPoint(buckets: Int32Array): number /* int */ /* throws NotFoundException */ {
+ // Find the tallest peak in the histogram.
+ const numBuckets = buckets.length;
+ let maxBucketCount = 0;
+ let firstPeak = 0;
+ let firstPeakSize = 0;
+ for (let x = 0; x < numBuckets; x++) {
+ if (buckets[x] > firstPeakSize) {
+ firstPeak = x;
+ firstPeakSize = buckets[x];
+ }
+ if (buckets[x] > maxBucketCount) {
+ maxBucketCount = buckets[x];
+ }
+ }
- // If there is too little contrast in the image to pick a meaningful black point, throw rather
- // than waste time trying to decode the image, and risk false positives.
- if (secondPeak - firstPeak <= numBuckets / 16) {
- throw new NotFoundException();
- }
+ // Find the second-tallest peak which is somewhat far from the tallest peak.
+ let secondPeak = 0;
+ let secondPeakScore = 0;
+
+ for (let x = 0; x < numBuckets; x++) {
+ const distanceToBiggest = x - firstPeak;
+ // Encourage more distant second peaks by multiplying by square of distance.
+ const score = buckets[x] * distanceToBiggest * distanceToBiggest;
+ if (score > secondPeakScore) {
+ secondPeak = x;
+ secondPeakScore = score;
+ }
+ }
- // Find a valley between them that is low and closer to the white peak.
- let bestValley = secondPeak - 1;
- let bestValleyScore = -1;
- for (let x = secondPeak - 1; x > firstPeak; x--) {
- const fromFirst = x - firstPeak;
- const score = fromFirst * fromFirst * (secondPeak - x) * (maxBucketCount - buckets[x]);
- if (score > bestValleyScore) {
- bestValley = x;
- bestValleyScore = score;
- }
- }
+ // Make sure firstPeak corresponds to the black peak.
+ if (firstPeak > secondPeak) {
+ const temp = firstPeak;
+ firstPeak = secondPeak;
+ secondPeak = temp;
+ }
- return bestValley << GlobalHistogramBinarizer.LUMINANCE_SHIFT;
+ // If there is too little contrast in the image to pick a meaningful black point, throw rather
+ // than waste time trying to decode the image, and risk false positives.
+ if (secondPeak - firstPeak <= numBuckets / 16) {
+ throw new NotFoundException();
}
+ // Find a valley between them that is low and closer to the white peak.
+ let bestValley = secondPeak - 1;
+ let bestValleyScore = -1;
+ for (let x = secondPeak - 1; x > firstPeak; x--) {
+ const fromFirst = x - firstPeak;
+ const score = fromFirst * fromFirst * (secondPeak - x) * (maxBucketCount - buckets[x]);
+ if (score > bestValleyScore) {
+ bestValley = x;
+ bestValleyScore = score;
+ }
+ }
+
+ return bestValley << GlobalHistogramBinarizer.LUMINANCE_SHIFT;
+ }
+
}
diff --git a/src/core/common/GridSampler.ts b/src/core/common/GridSampler.ts
index 7d9c7b1d..8304e5db 100644
--- a/src/core/common/GridSampler.ts
+++ b/src/core/common/GridSampler.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common {*/
+/* namespace com.google.zxing.common { */
import BitMatrix from './BitMatrix';
import PerspectiveTransform from './PerspectiveTransform';
@@ -36,143 +36,143 @@ import NotFoundException from '../NotFoundException';
*/
abstract class GridSampler {
- /**
- * Samples an image for a rectangular matrix of bits of the given dimension. The sampling
- * transformation is determined by the coordinates of 4 points, in the original and transformed
- * image space.
- *
- * @param image image to sample
- * @param dimensionX width of {@link BitMatrix} to sample from image
- * @param dimensionY height of {@link BitMatrix} to sample from image
- * @param p1ToX point 1 preimage X
- * @param p1ToY point 1 preimage Y
- * @param p2ToX point 2 preimage X
- * @param p2ToY point 2 preimage Y
- * @param p3ToX point 3 preimage X
- * @param p3ToY point 3 preimage Y
- * @param p4ToX point 4 preimage X
- * @param p4ToY point 4 preimage Y
- * @param p1FromX point 1 image X
- * @param p1FromY point 1 image Y
- * @param p2FromX point 2 image X
- * @param p2FromY point 2 image Y
- * @param p3FromX point 3 image X
- * @param p3FromY point 3 image Y
- * @param p4FromX point 4 image X
- * @param p4FromY point 4 image Y
- *
- * @return {@link BitMatrix} representing a grid of points sampled from the image within a region
- * defined by the "from" parameters
- *
- * @throws NotFoundException if image can't be sampled, for example, if the transformation defined
- * by the given points is invalid or results in sampling outside the image boundaries
- */
- public abstract sampleGrid(
- image: BitMatrix,
- dimensionX: number /*int*/,
- dimensionY: number /*int*/,
- p1ToX: number/*float*/, p1ToY: number/*float*/,
- p2ToX: number/*float*/, p2ToY: number/*float*/,
- p3ToX: number/*float*/, p3ToY: number/*float*/,
- p4ToX: number/*float*/, p4ToY: number/*float*/,
- p1FromX: number/*float*/, p1FromY: number/*float*/,
- p2FromX: number/*float*/, p2FromY: number/*float*/,
- p3FromX: number/*float*/, p3FromY: number/*float*/,
- p4FromX: number/*float*/, p4FromY: number/*float*/
- ): BitMatrix; /*throws NotFoundException*/
-
- public abstract sampleGridWithTransform(
- image: BitMatrix,
- dimensionX: number /*int*/,
- dimensionY: number /*int*/,
- transform: PerspectiveTransform
- ): BitMatrix; /*throws NotFoundException*/
-
- /**
- * Checks a set of points that have been transformed to sample points on an image against
- * the image's dimensions to see if the point are even within the image.
- *
- * This method will actually "nudge" the endpoints back onto the image if they are found to be
- * barely (less than 1 pixel) off the image. This accounts for imperfect detection of finder
- * patterns in an image where the QR Code runs all the way to the image border.
- *
- * For efficiency, the method will check points from either end of the line until one is found
- * to be within the image. Because the set of points are assumed to be linear, this is valid.
- *
- * @param image image into which the points should map
- * @param points actual points in x1,y1,...,xn,yn form
- * @throws NotFoundException if an endpoint is lies outside the image boundaries
- */
- protected static checkAndNudgePoints(
- image: BitMatrix,
- points: Float32Array
- ): void /*throws NotFoundException*/ {
-
- const width: number /*int*/ = image.getWidth();
- const height: number /*int*/ = image.getHeight();
-
- // Check and nudge points from start until we see some that are OK:
- let nudged: boolean = true;
-
- for (let offset = 0; offset < points.length && nudged; offset += 2) {
-
- const x = Math.floor(points[offset]);
- const y = Math.floor(points[offset + 1]);
-
- if (x < -1 || x > width || y < -1 || y > height) {
- throw new NotFoundException();
- }
-
- nudged = false;
-
- if (x === -1) {
- points[offset] = 0.0;
- nudged = true;
- } else if (x === width) {
- points[offset] = width - 1;
- nudged = true;
- }
-
- if (y === -1) {
- points[offset + 1] = 0.0;
- nudged = true;
- } else if (y === height) {
- points[offset + 1] = height - 1;
- nudged = true;
- }
- }
-
- // Check and nudge points from end:
+ /**
+ * Samples an image for a rectangular matrix of bits of the given dimension. The sampling
+ * transformation is determined by the coordinates of 4 points, in the original and transformed
+ * image space.
+ *
+ * @param image image to sample
+ * @param dimensionX width of {@link BitMatrix} to sample from image
+ * @param dimensionY height of {@link BitMatrix} to sample from image
+ * @param p1ToX point 1 preimage X
+ * @param p1ToY point 1 preimage Y
+ * @param p2ToX point 2 preimage X
+ * @param p2ToY point 2 preimage Y
+ * @param p3ToX point 3 preimage X
+ * @param p3ToY point 3 preimage Y
+ * @param p4ToX point 4 preimage X
+ * @param p4ToY point 4 preimage Y
+ * @param p1FromX point 1 image X
+ * @param p1FromY point 1 image Y
+ * @param p2FromX point 2 image X
+ * @param p2FromY point 2 image Y
+ * @param p3FromX point 3 image X
+ * @param p3FromY point 3 image Y
+ * @param p4FromX point 4 image X
+ * @param p4FromY point 4 image Y
+ *
+ * @return {@link BitMatrix} representing a grid of points sampled from the image within a region
+ * defined by the "from" parameters
+ *
+ * @throws NotFoundException if image can't be sampled, for example, if the transformation defined
+ * by the given points is invalid or results in sampling outside the image boundaries
+ */
+ public abstract sampleGrid(
+ image: BitMatrix,
+ dimensionX: number /* int */,
+ dimensionY: number /* int */,
+ p1ToX: number/* float */, p1ToY: number/* float */,
+ p2ToX: number/* float */, p2ToY: number/* float */,
+ p3ToX: number/* float */, p3ToY: number/* float */,
+ p4ToX: number/* float */, p4ToY: number/* float */,
+ p1FromX: number/* float */, p1FromY: number/* float */,
+ p2FromX: number/* float */, p2FromY: number/* float */,
+ p3FromX: number/* float */, p3FromY: number/* float */,
+ p4FromX: number/* float */, p4FromY: number/* float */
+ ): BitMatrix; /* throws NotFoundException */
+
+ public abstract sampleGridWithTransform(
+ image: BitMatrix,
+ dimensionX: number /* int */,
+ dimensionY: number /* int */,
+ transform: PerspectiveTransform
+ ): BitMatrix; /* throws NotFoundException */
+
+ /**
+ * Checks a set of points that have been transformed to sample points on an image against
+ * the image's dimensions to see if the point are even within the image.
+ *
+ * This method will actually "nudge" the endpoints back onto the image if they are found to be
+ * barely (less than 1 pixel) off the image. This accounts for imperfect detection of finder
+ * patterns in an image where the QR Code runs all the way to the image border.
+ *
+ * For efficiency, the method will check points from either end of the line until one is found
+ * to be within the image. Because the set of points are assumed to be linear, this is valid.
+ *
+ * @param image image into which the points should map
+ * @param points actual points in x1,y1,...,xn,yn form
+ * @throws NotFoundException if an endpoint is lies outside the image boundaries
+ */
+ protected static checkAndNudgePoints(
+ image: BitMatrix,
+ points: Float32Array
+ ): void /* throws NotFoundException */ {
+
+ const width: number /* int */ = image.getWidth();
+ const height: number /* int */ = image.getHeight();
+
+ // Check and nudge points from start until we see some that are OK:
+ let nudged: boolean = true;
+
+ for (let offset = 0; offset < points.length && nudged; offset += 2) {
+
+ const x = Math.floor(points[offset]);
+ const y = Math.floor(points[offset + 1]);
+
+ if (x < -1 || x > width || y < -1 || y > height) {
+ throw new NotFoundException();
+ }
+
+ nudged = false;
+
+ if (x === -1) {
+ points[offset] = 0.0;
+ nudged = true;
+ } else if (x === width) {
+ points[offset] = width - 1;
+ nudged = true;
+ }
+
+ if (y === -1) {
+ points[offset + 1] = 0.0;
nudged = true;
+ } else if (y === height) {
+ points[offset + 1] = height - 1;
+ nudged = true;
+ }
+ }
+
+ // Check and nudge points from end:
+ nudged = true;
+
+ for (let offset = points.length - 2; offset >= 0 && nudged; offset -= 2) {
+
+ const x = Math.floor(points[offset]);
+ const y = Math.floor(points[offset + 1]);
+
+ if (x < -1 || x > width || y < -1 || y > height) {
+ throw new NotFoundException();
+ }
- for (let offset = points.length - 2; offset >= 0 && nudged; offset -= 2) {
-
- const x = Math.floor(points[offset]);
- const y = Math.floor(points[offset + 1]);
-
- if (x < -1 || x > width || y < -1 || y > height) {
- throw new NotFoundException();
- }
-
- nudged = false;
-
- if (x === -1) {
- points[offset] = 0.0;
- nudged = true;
- } else if (x === width) {
- points[offset] = width - 1;
- nudged = true;
- }
-
- if (y === -1) {
- points[offset + 1] = 0.0;
- nudged = true;
- } else if (y === height) {
- points[offset + 1] = height - 1;
- nudged = true;
- }
- }
+ nudged = false;
+
+ if (x === -1) {
+ points[offset] = 0.0;
+ nudged = true;
+ } else if (x === width) {
+ points[offset] = width - 1;
+ nudged = true;
+ }
+
+ if (y === -1) {
+ points[offset + 1] = 0.0;
+ nudged = true;
+ } else if (y === height) {
+ points[offset + 1] = height - 1;
+ nudged = true;
+ }
}
+ }
}
diff --git a/src/core/common/GridSamplerInstance.ts b/src/core/common/GridSamplerInstance.ts
index 288afd46..fba54aaa 100644
--- a/src/core/common/GridSamplerInstance.ts
+++ b/src/core/common/GridSamplerInstance.ts
@@ -3,26 +3,26 @@ import DefaultGridSampler from './DefaultGridSampler';
export default class GridSamplerInstance {
- private static gridSampler: GridSampler = new DefaultGridSampler();
+ private static gridSampler: GridSampler = new DefaultGridSampler();
- /**
- * Sets the implementation of GridSampler used by the library. One global
- * instance is stored, which may sound problematic. But, the implementation provided
- * ought to be appropriate for the entire platform, and all uses of this library
- * in the whole lifetime of the JVM. For instance, an Android activity can swap in
- * an implementation that takes advantage of native platform libraries.
- *
- * @param newGridSampler The platform-specific object to install.
- */
- public static setGridSampler(newGridSampler: GridSampler): void {
- GridSamplerInstance.gridSampler = newGridSampler;
- }
+ /**
+ * Sets the implementation of GridSampler used by the library. One global
+ * instance is stored, which may sound problematic. But, the implementation provided
+ * ought to be appropriate for the entire platform, and all uses of this library
+ * in the whole lifetime of the JVM. For instance, an Android activity can swap in
+ * an implementation that takes advantage of native platform libraries.
+ *
+ * @param newGridSampler The platform-specific object to install.
+ */
+ public static setGridSampler(newGridSampler: GridSampler): void {
+ GridSamplerInstance.gridSampler = newGridSampler;
+ }
- /**
- * @return the current implementation of GridSampler
- */
- public static getInstance(): GridSampler {
- return GridSamplerInstance.gridSampler;
- }
+ /**
+ * @return the current implementation of GridSampler
+ */
+ public static getInstance(): GridSampler {
+ return GridSamplerInstance.gridSampler;
+ }
}
diff --git a/src/core/common/HybridBinarizer.ts b/src/core/common/HybridBinarizer.ts
index 11688a3e..ccfd88d9 100644
--- a/src/core/common/HybridBinarizer.ts
+++ b/src/core/common/HybridBinarizer.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common {*/
+/* namespace com.google.zxing.common { */
import Binarizer from '../Binarizer';
import LuminanceSource from '../LuminanceSource';
@@ -40,202 +40,202 @@ import BitMatrix from './BitMatrix';
*/
export default class HybridBinarizer extends GlobalHistogramBinarizer {
- // This class uses 5x5 blocks to compute local luminance, where each block is 8x8 pixels.
- // So this is the smallest dimension in each axis we can accept.
- private static BLOCK_SIZE_POWER = 3;
- private static BLOCK_SIZE = 1 << HybridBinarizer.BLOCK_SIZE_POWER; // ...0100...00
- private static BLOCK_SIZE_MASK = HybridBinarizer.BLOCK_SIZE - 1; // ...0011...11
- private static MINIMUM_DIMENSION = HybridBinarizer.BLOCK_SIZE * 5;
- private static MIN_DYNAMIC_RANGE = 24;
+ // This class uses 5x5 blocks to compute local luminance, where each block is 8x8 pixels.
+ // So this is the smallest dimension in each axis we can accept.
+ private static BLOCK_SIZE_POWER = 3;
+ private static BLOCK_SIZE = 1 << HybridBinarizer.BLOCK_SIZE_POWER; // ...0100...00
+ private static BLOCK_SIZE_MASK = HybridBinarizer.BLOCK_SIZE - 1; // ...0011...11
+ private static MINIMUM_DIMENSION = HybridBinarizer.BLOCK_SIZE * 5;
+ private static MIN_DYNAMIC_RANGE = 24;
- private matrix: BitMatrix | null = null;
+ private matrix: BitMatrix | null = null;
- public constructor(source: LuminanceSource) {
- super(source);
- }
+ public constructor(source: LuminanceSource) {
+ super(source);
+ }
- /**
- * Calculates the final BitMatrix once for all requests. This could be called once from the
- * constructor instead, but there are some advantages to doing it lazily, such as making
- * profiling easier, and not doing heavy lifting when callers don't expect it.
- */
- /*@Override*/
- public getBlackMatrix(): BitMatrix /*throws NotFoundException*/ {
- if (this.matrix !== null) {
- return this.matrix;
+ /**
+ * Calculates the final BitMatrix once for all requests. This could be called once from the
+ * constructor instead, but there are some advantages to doing it lazily, such as making
+ * profiling easier, and not doing heavy lifting when callers don't expect it.
+ */
+ /* @Override */
+ public getBlackMatrix(): BitMatrix /* throws NotFoundException */ {
+ if (this.matrix !== null) {
+ return this.matrix;
+ }
+ const source = this.getLuminanceSource();
+ const width = source.getWidth();
+ const height = source.getHeight();
+ if (width >= HybridBinarizer.MINIMUM_DIMENSION && height >= HybridBinarizer.MINIMUM_DIMENSION) {
+ const luminances = source.getMatrix();
+ let subWidth = width >> HybridBinarizer.BLOCK_SIZE_POWER;
+ if ((width & HybridBinarizer.BLOCK_SIZE_MASK) !== 0) {
+ subWidth++;
+ }
+ let subHeight = height >> HybridBinarizer.BLOCK_SIZE_POWER;
+ if ((height & HybridBinarizer.BLOCK_SIZE_MASK) !== 0) {
+ subHeight++;
+ }
+ const blackPoints = HybridBinarizer.calculateBlackPoints(luminances, subWidth, subHeight, width, height);
+
+ const newMatrix = new BitMatrix(width, height);
+ HybridBinarizer.calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);
+ this.matrix = newMatrix;
+ } else {
+ // If the image is too small, fall back to the global histogram approach.
+ this.matrix = super.getBlackMatrix();
+ }
+ return this.matrix;
+ }
+
+ /* @Override */
+ public createBinarizer(source: LuminanceSource): Binarizer {
+ return new HybridBinarizer(source);
+ }
+
+ /**
+ * For each block in the image, calculate the average black point using a 5x5 grid
+ * of the blocks around it. Also handles the corner cases (fractional blocks are computed based
+ * on the last pixels in the row/column which are also used in the previous block).
+ */
+ private static calculateThresholdForBlock(luminances: Uint8ClampedArray,
+ subWidth: number /* int */,
+ subHeight: number /* int */,
+ width: number /* int */,
+ height: number /* int */,
+ blackPoints: Int32Array[],
+ matrix: BitMatrix): void {
+ const maxYOffset = height - HybridBinarizer.BLOCK_SIZE;
+ const maxXOffset = width - HybridBinarizer.BLOCK_SIZE;
+ for (let y = 0; y < subHeight; y++) {
+ let yoffset = y << HybridBinarizer.BLOCK_SIZE_POWER;
+ if (yoffset > maxYOffset) {
+ yoffset = maxYOffset;
+ }
+ const top = HybridBinarizer.cap(y, 2, subHeight - 3);
+ for (let x = 0; x < subWidth; x++) {
+ let xoffset = x << HybridBinarizer.BLOCK_SIZE_POWER;
+ if (xoffset > maxXOffset) {
+ xoffset = maxXOffset;
}
- const source = this.getLuminanceSource();
- const width = source.getWidth();
- const height = source.getHeight();
- if (width >= HybridBinarizer.MINIMUM_DIMENSION && height >= HybridBinarizer.MINIMUM_DIMENSION) {
- const luminances = source.getMatrix();
- let subWidth = width >> HybridBinarizer.BLOCK_SIZE_POWER;
- if ((width & HybridBinarizer.BLOCK_SIZE_MASK) !== 0) {
- subWidth++;
- }
- let subHeight = height >> HybridBinarizer.BLOCK_SIZE_POWER;
- if ((height & HybridBinarizer.BLOCK_SIZE_MASK) !== 0) {
- subHeight++;
- }
- const blackPoints = HybridBinarizer.calculateBlackPoints(luminances, subWidth, subHeight, width, height);
-
- const newMatrix = new BitMatrix(width, height);
- HybridBinarizer.calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);
- this.matrix = newMatrix;
- } else {
- // If the image is too small, fall back to the global histogram approach.
- this.matrix = super.getBlackMatrix();
+ const left = HybridBinarizer.cap(x, 2, subWidth - 3);
+ let sum = 0;
+ for (let z = -2; z <= 2; z++) {
+ const blackRow = blackPoints[top + z];
+ sum += blackRow[left - 2] + blackRow[left - 1] + blackRow[left] + blackRow[left + 1] + blackRow[left + 2];
}
- return this.matrix;
+ const average = sum / 25;
+ HybridBinarizer.thresholdBlock(luminances, xoffset, yoffset, average, width, matrix);
+ }
}
+ }
- /*@Override*/
- public createBinarizer(source: LuminanceSource): Binarizer {
- return new HybridBinarizer(source);
- }
+ private static cap(value: number /* int */, min: number /* int */, max: number /* int */): number /* int */ {
+ return value < min ? min : value > max ? max : value;
+ }
- /**
- * For each block in the image, calculate the average black point using a 5x5 grid
- * of the blocks around it. Also handles the corner cases (fractional blocks are computed based
- * on the last pixels in the row/column which are also used in the previous block).
- */
- private static calculateThresholdForBlock(luminances: Uint8ClampedArray,
- subWidth: number /*int*/,
- subHeight: number /*int*/,
- width: number /*int*/,
- height: number /*int*/,
- blackPoints: Int32Array[],
- matrix: BitMatrix): void {
- const maxYOffset = height - HybridBinarizer.BLOCK_SIZE;
- const maxXOffset = width - HybridBinarizer.BLOCK_SIZE;
- for (let y = 0; y < subHeight; y++) {
- let yoffset = y << HybridBinarizer.BLOCK_SIZE_POWER;
- if (yoffset > maxYOffset) {
- yoffset = maxYOffset;
- }
- const top = HybridBinarizer.cap(y, 2, subHeight - 3);
- for (let x = 0; x < subWidth; x++) {
- let xoffset = x << HybridBinarizer.BLOCK_SIZE_POWER;
- if (xoffset > maxXOffset) {
- xoffset = maxXOffset;
- }
- const left = HybridBinarizer.cap(x, 2, subWidth - 3);
- let sum = 0;
- for (let z = -2; z <= 2; z++) {
- const blackRow = blackPoints[top + z];
- sum += blackRow[left - 2] + blackRow[left - 1] + blackRow[left] + blackRow[left + 1] + blackRow[left + 2];
- }
- const average = sum / 25;
- HybridBinarizer.thresholdBlock(luminances, xoffset, yoffset, average, width, matrix);
- }
+ /**
+ * Applies a single threshold to a block of pixels.
+ */
+ private static thresholdBlock(luminances: Uint8ClampedArray,
+ xoffset: number /* int */,
+ yoffset: number /* int */,
+ threshold: number /* int */,
+ stride: number /* int */,
+ matrix: BitMatrix): void {
+ for (let y = 0, offset = yoffset * stride + xoffset; y < HybridBinarizer.BLOCK_SIZE; y++, offset += stride) {
+ for (let x = 0; x < HybridBinarizer.BLOCK_SIZE; x++) {
+ // Comparison needs to be <= so that black == 0 pixels are black even if the threshold is 0.
+ if ((luminances[offset + x] & 0xFF) <= threshold) {
+ matrix.set(xoffset + x, yoffset + y);
}
+ }
}
+ }
- private static cap(value: number /*int*/, min: number /*int*/, max: number /*int*/): number /*int*/ {
- return value < min ? min : value > max ? max : value;
- }
-
- /**
- * Applies a single threshold to a block of pixels.
- */
- private static thresholdBlock(luminances: Uint8ClampedArray,
- xoffset: number /*int*/,
- yoffset: number /*int*/,
- threshold: number /*int*/,
- stride: number /*int*/,
- matrix: BitMatrix): void {
- for (let y = 0, offset = yoffset * stride + xoffset; y < HybridBinarizer.BLOCK_SIZE; y++ , offset += stride) {
- for (let x = 0; x < HybridBinarizer.BLOCK_SIZE; x++) {
- // Comparison needs to be <= so that black == 0 pixels are black even if the threshold is 0.
- if ((luminances[offset + x] & 0xFF) <= threshold) {
- matrix.set(xoffset + x, yoffset + y);
- }
+ /**
+ * Calculates a single black point for each block of pixels and saves it away.
+ * See the following thread for a discussion of this algorithm:
+ * http://groups.google.com/group/zxing/browse_thread/thread/d06efa2c35a7ddc0
+ */
+ private static calculateBlackPoints(luminances: Uint8ClampedArray,
+ subWidth: number /* int */,
+ subHeight: number /* int */,
+ width: number /* int */,
+ height: number /* int */): Int32Array[] {
+ const maxYOffset = height - HybridBinarizer.BLOCK_SIZE;
+ const maxXOffset = width - HybridBinarizer.BLOCK_SIZE;
+ // tslint:disable-next-line:whitespace
+ const blackPoints = new Array(subHeight);// subWidth
+
+ for (let y = 0; y < subHeight; y++) {
+ blackPoints[y] = new Int32Array(subWidth);
+ let yoffset = y << HybridBinarizer.BLOCK_SIZE_POWER;
+ if (yoffset > maxYOffset) {
+ yoffset = maxYOffset;
+ }
+ for (let x = 0; x < subWidth; x++) {
+ let xoffset = x << HybridBinarizer.BLOCK_SIZE_POWER;
+ if (xoffset > maxXOffset) {
+ xoffset = maxXOffset;
+ }
+ let sum = 0;
+ let min = 0xFF;
+ let max = 0;
+ for (let yy = 0, offset = yoffset * width + xoffset; yy < HybridBinarizer.BLOCK_SIZE; yy++, offset += width) {
+ for (let xx = 0; xx < HybridBinarizer.BLOCK_SIZE; xx++) {
+ const pixel = luminances[offset + xx] & 0xFF;
+ sum += pixel;
+ // still looking for good contrast
+ if (pixel < min) {
+ min = pixel;
}
+ if (pixel > max) {
+ max = pixel;
+ }
+ }
+ // short-circuit min/max tests once dynamic range is met
+ if (max - min > HybridBinarizer.MIN_DYNAMIC_RANGE) {
+ // finish the rest of the rows quickly
+ for (yy++, offset += width; yy < HybridBinarizer.BLOCK_SIZE; yy++, offset += width) {
+ for (let xx = 0; xx < HybridBinarizer.BLOCK_SIZE; xx++) {
+ sum += luminances[offset + xx] & 0xFF;
+ }
+ }
+ }
}
- }
- /**
- * Calculates a single black point for each block of pixels and saves it away.
- * See the following thread for a discussion of this algorithm:
- * http://groups.google.com/group/zxing/browse_thread/thread/d06efa2c35a7ddc0
- */
- private static calculateBlackPoints(luminances: Uint8ClampedArray,
- subWidth: number /*int*/,
- subHeight: number /*int*/,
- width: number /*int*/,
- height: number /*int*/): Int32Array[] {
- const maxYOffset = height - HybridBinarizer.BLOCK_SIZE;
- const maxXOffset = width - HybridBinarizer.BLOCK_SIZE;
- // tslint:disable-next-line:whitespace
- const blackPoints = new Array(subHeight);// subWidth
-
- for (let y = 0; y < subHeight; y++) {
- blackPoints[y] = new Int32Array(subWidth);
- let yoffset = y << HybridBinarizer.BLOCK_SIZE_POWER;
- if (yoffset > maxYOffset) {
- yoffset = maxYOffset;
- }
- for (let x = 0; x < subWidth; x++) {
- let xoffset = x << HybridBinarizer.BLOCK_SIZE_POWER;
- if (xoffset > maxXOffset) {
- xoffset = maxXOffset;
- }
- let sum = 0;
- let min = 0xFF;
- let max = 0;
- for (let yy = 0, offset = yoffset * width + xoffset; yy < HybridBinarizer.BLOCK_SIZE; yy++ , offset += width) {
- for (let xx = 0; xx < HybridBinarizer.BLOCK_SIZE; xx++) {
- const pixel = luminances[offset + xx] & 0xFF;
- sum += pixel;
- // still looking for good contrast
- if (pixel < min) {
- min = pixel;
- }
- if (pixel > max) {
- max = pixel;
- }
- }
- // short-circuit min/max tests once dynamic range is met
- if (max - min > HybridBinarizer.MIN_DYNAMIC_RANGE) {
- // finish the rest of the rows quickly
- for (yy++ , offset += width; yy < HybridBinarizer.BLOCK_SIZE; yy++ , offset += width) {
- for (let xx = 0; xx < HybridBinarizer.BLOCK_SIZE; xx++) {
- sum += luminances[offset + xx] & 0xFF;
- }
- }
- }
- }
-
- // The default estimate is the average of the values in the block.
- let average = sum >> (HybridBinarizer.BLOCK_SIZE_POWER * 2);
- if (max - min <= HybridBinarizer.MIN_DYNAMIC_RANGE) {
- // If variation within the block is low, assume this is a block with only light or only
- // dark pixels. In that case we do not want to use the average, as it would divide this
- // low contrast area into black and white pixels, essentially creating data out of noise.
- //
- // The default assumption is that the block is light/background. Since no estimate for
- // the level of dark pixels exists locally, use half the min for the block.
- average = min / 2;
-
- if (y > 0 && x > 0) {
- // Correct the "white background" assumption for blocks that have neighbors by comparing
- // the pixels in this block to the previously calculated black points. This is based on
- // the fact that dark barcode symbology is always surrounded by some amount of light
- // background for which reasonable black point estimates were made. The bp estimated at
- // the boundaries is used for the interior.
-
- // The (min < bp) is arbitrary but works better than other heuristics that were tried.
- const averageNeighborBlackPoint =
- (blackPoints[y - 1][x] + (2 * blackPoints[y][x - 1]) + blackPoints[y - 1][x - 1]) / 4;
- if (min < averageNeighborBlackPoint) {
- average = averageNeighborBlackPoint;
- }
- }
- }
- blackPoints[y][x] = average;
+ // The default estimate is the average of the values in the block.
+ let average = sum >> (HybridBinarizer.BLOCK_SIZE_POWER * 2);
+ if (max - min <= HybridBinarizer.MIN_DYNAMIC_RANGE) {
+ // If variation within the block is low, assume this is a block with only light or only
+ // dark pixels. In that case we do not want to use the average, as it would divide this
+ // low contrast area into black and white pixels, essentially creating data out of noise.
+ //
+ // The default assumption is that the block is light/background. Since no estimate for
+ // the level of dark pixels exists locally, use half the min for the block.
+ average = min / 2;
+
+ if (y > 0 && x > 0) {
+ // Correct the "white background" assumption for blocks that have neighbors by comparing
+ // the pixels in this block to the previously calculated black points. This is based on
+ // the fact that dark barcode symbology is always surrounded by some amount of light
+ // background for which reasonable black point estimates were made. The bp estimated at
+ // the boundaries is used for the interior.
+
+ // The (min < bp) is arbitrary but works better than other heuristics that were tried.
+ const averageNeighborBlackPoint =
+ (blackPoints[y - 1][x] + (2 * blackPoints[y][x - 1]) + blackPoints[y - 1][x - 1]) / 4;
+ if (min < averageNeighborBlackPoint) {
+ average = averageNeighborBlackPoint;
}
+ }
}
- return blackPoints;
+ blackPoints[y][x] = average;
+ }
}
+ return blackPoints;
+ }
}
diff --git a/src/core/common/PerspectiveTransform.ts b/src/core/common/PerspectiveTransform.ts
index 8f110e61..1ed3a641 100644
--- a/src/core/common/PerspectiveTransform.ts
+++ b/src/core/common/PerspectiveTransform.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common {*/
+/* namespace com.google.zxing.common { */
/**
* This class implements a perspective transform in two dimensions. Given four source and four
@@ -25,145 +25,145 @@
*/
export default class PerspectiveTransform {
- private constructor(private a11: number/*float*/, private a21: number/*float*/, private a31: number/*float*/,
- private a12: number/*float*/, private a22: number/*float*/, private a32: number/*float*/,
- private a13: number/*float*/, private a23: number/*float*/, private a33: number/*float*/) { }
-
- public static quadrilateralToQuadrilateral(
- x0: number/*float*/, y0: number/*float*/,
- x1: number/*float*/, y1: number/*float*/,
- x2: number/*float*/, y2: number/*float*/,
- x3: number/*float*/, y3: number/*float*/,
- x0p: number/*float*/, y0p: number/*float*/,
- x1p: number/*float*/, y1p: number/*float*/,
- x2p: number/*float*/, y2p: number/*float*/,
- x3p: number/*float*/, y3p: number/*float*/
- ): PerspectiveTransform {
-
- const qToS = PerspectiveTransform.quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3);
- const sToQ = PerspectiveTransform.squareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p);
-
- return sToQ.times(qToS);
+ private constructor(private a11: number/* float */, private a21: number/* float */, private a31: number/* float */,
+ private a12: number/* float */, private a22: number/* float */, private a32: number/* float */,
+ private a13: number/* float */, private a23: number/* float */, private a33: number/* float */) { }
+
+ public static quadrilateralToQuadrilateral(
+ x0: number/* float */, y0: number/* float */,
+ x1: number/* float */, y1: number/* float */,
+ x2: number/* float */, y2: number/* float */,
+ x3: number/* float */, y3: number/* float */,
+ x0p: number/* float */, y0p: number/* float */,
+ x1p: number/* float */, y1p: number/* float */,
+ x2p: number/* float */, y2p: number/* float */,
+ x3p: number/* float */, y3p: number/* float */
+ ): PerspectiveTransform {
+
+ const qToS = PerspectiveTransform.quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3);
+ const sToQ = PerspectiveTransform.squareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p);
+
+ return sToQ.times(qToS);
+ }
+
+ public transformPoints(points: Float32Array): void {
+
+ const max = points.length;
+
+ const a11 = this.a11;
+ const a12 = this.a12;
+ const a13 = this.a13;
+ const a21 = this.a21;
+ const a22 = this.a22;
+ const a23 = this.a23;
+ const a31 = this.a31;
+ const a32 = this.a32;
+ const a33 = this.a33;
+
+ for (let i = 0; i < max; i += 2) {
+ const x = points[i];
+ const y = points[i + 1];
+ const denominator = a13 * x + a23 * y + a33;
+ points[i] = (a11 * x + a21 * y + a31) / denominator;
+ points[i + 1] = (a12 * x + a22 * y + a32) / denominator;
}
+ }
- public transformPoints(points: Float32Array): void {
-
- const max = points.length;
-
- const a11 = this.a11;
- const a12 = this.a12;
- const a13 = this.a13;
- const a21 = this.a21;
- const a22 = this.a22;
- const a23 = this.a23;
- const a31 = this.a31;
- const a32 = this.a32;
- const a33 = this.a33;
-
- for (let i = 0; i < max; i += 2) {
- const x = points[i];
- const y = points[i + 1];
- const denominator = a13 * x + a23 * y + a33;
- points[i] = (a11 * x + a21 * y + a31) / denominator;
- points[i + 1] = (a12 * x + a22 * y + a32) / denominator;
- }
- }
-
- public transformPointsWithValues(xValues: Float32Array, yValues: Float32Array): void {
+ public transformPointsWithValues(xValues: Float32Array, yValues: Float32Array): void {
- const a11 = this.a11;
- const a12 = this.a12;
- const a13 = this.a13;
- const a21 = this.a21;
- const a22 = this.a22;
- const a23 = this.a23;
- const a31 = this.a31;
- const a32 = this.a32;
- const a33 = this.a33;
+ const a11 = this.a11;
+ const a12 = this.a12;
+ const a13 = this.a13;
+ const a21 = this.a21;
+ const a22 = this.a22;
+ const a23 = this.a23;
+ const a31 = this.a31;
+ const a32 = this.a32;
+ const a33 = this.a33;
- const n = xValues.length;
+ const n = xValues.length;
- for (let i = 0; i < n; i++) {
- const x = xValues[i];
- const y = yValues[i];
- const denominator = a13 * x + a23 * y + a33;
+ for (let i = 0; i < n; i++) {
+ const x = xValues[i];
+ const y = yValues[i];
+ const denominator = a13 * x + a23 * y + a33;
- xValues[i] = (a11 * x + a21 * y + a31) / denominator;
- yValues[i] = (a12 * x + a22 * y + a32) / denominator;
- }
+ xValues[i] = (a11 * x + a21 * y + a31) / denominator;
+ yValues[i] = (a12 * x + a22 * y + a32) / denominator;
}
-
- public static squareToQuadrilateral(
- x0: number/*float*/, y0: number/*float*/,
- x1: number/*float*/, y1: number/*float*/,
- x2: number/*float*/, y2: number/*float*/,
- x3: number/*float*/, y3: number/*float*/
- ): PerspectiveTransform {
-
- const dx3 = x0 - x1 + x2 - x3;
- const dy3 = y0 - y1 + y2 - y3;
-
- if (dx3 === 0.0 && dy3 === 0.0) {
- // Affine
- return new PerspectiveTransform(x1 - x0, x2 - x1, x0,
- y1 - y0, y2 - y1, y0,
- 0.0, 0.0, 1.0);
- } else {
- const dx1 = x1 - x2;
- const dx2 = x3 - x2;
- const dy1 = y1 - y2;
- const dy2 = y3 - y2;
-
- const denominator = dx1 * dy2 - dx2 * dy1;
-
- const a13 = (dx3 * dy2 - dx2 * dy3) / denominator;
- const a23 = (dx1 * dy3 - dx3 * dy1) / denominator;
-
- return new PerspectiveTransform(
- x1 - x0 + a13 * x1, x3 - x0 + a23 * x3, x0,
- y1 - y0 + a13 * y1, y3 - y0 + a23 * y3, y0,
- a13, a23, 1.0
- );
- }
- }
-
- public static quadrilateralToSquare(
- x0: number/*float*/, y0: number/*float*/,
- x1: number/*float*/, y1: number/*float*/,
- x2: number/*float*/, y2: number/*float*/,
- x3: number/*float*/, y3: number/*float*/
- ): PerspectiveTransform {
- // Here, the adjoint serves as the inverse:
- return PerspectiveTransform.squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3).buildAdjoint();
- }
-
- protected buildAdjoint(): PerspectiveTransform {
- // Adjoint is the transpose of the cofactor matrix:
- return new PerspectiveTransform(
- this.a22 * this.a33 - this.a23 * this.a32,
- this.a23 * this.a31 - this.a21 * this.a33,
- this.a21 * this.a32 - this.a22 * this.a31,
- this.a13 * this.a32 - this.a12 * this.a33,
- this.a11 * this.a33 - this.a13 * this.a31,
- this.a12 * this.a31 - this.a11 * this.a32,
- this.a12 * this.a23 - this.a13 * this.a22,
- this.a13 * this.a21 - this.a11 * this.a23,
- this.a11 * this.a22 - this.a12 * this.a21
- );
- }
-
- protected times(other: PerspectiveTransform): PerspectiveTransform {
- return new PerspectiveTransform(
- this.a11 * other.a11 + this.a21 * other.a12 + this.a31 * other.a13,
- this.a11 * other.a21 + this.a21 * other.a22 + this.a31 * other.a23,
- this.a11 * other.a31 + this.a21 * other.a32 + this.a31 * other.a33,
- this.a12 * other.a11 + this.a22 * other.a12 + this.a32 * other.a13,
- this.a12 * other.a21 + this.a22 * other.a22 + this.a32 * other.a23,
- this.a12 * other.a31 + this.a22 * other.a32 + this.a32 * other.a33,
- this.a13 * other.a11 + this.a23 * other.a12 + this.a33 * other.a13,
- this.a13 * other.a21 + this.a23 * other.a22 + this.a33 * other.a23,
- this.a13 * other.a31 + this.a23 * other.a32 + this.a33 * other.a33
- );
+ }
+
+ public static squareToQuadrilateral(
+ x0: number/* float */, y0: number/* float */,
+ x1: number/* float */, y1: number/* float */,
+ x2: number/* float */, y2: number/* float */,
+ x3: number/* float */, y3: number/* float */
+ ): PerspectiveTransform {
+
+ const dx3 = x0 - x1 + x2 - x3;
+ const dy3 = y0 - y1 + y2 - y3;
+
+ if (dx3 === 0.0 && dy3 === 0.0) {
+ // Affine
+ return new PerspectiveTransform(x1 - x0, x2 - x1, x0,
+ y1 - y0, y2 - y1, y0,
+ 0.0, 0.0, 1.0);
+ } else {
+ const dx1 = x1 - x2;
+ const dx2 = x3 - x2;
+ const dy1 = y1 - y2;
+ const dy2 = y3 - y2;
+
+ const denominator = dx1 * dy2 - dx2 * dy1;
+
+ const a13 = (dx3 * dy2 - dx2 * dy3) / denominator;
+ const a23 = (dx1 * dy3 - dx3 * dy1) / denominator;
+
+ return new PerspectiveTransform(
+ x1 - x0 + a13 * x1, x3 - x0 + a23 * x3, x0,
+ y1 - y0 + a13 * y1, y3 - y0 + a23 * y3, y0,
+ a13, a23, 1.0
+ );
}
+ }
+
+ public static quadrilateralToSquare(
+ x0: number/* float */, y0: number/* float */,
+ x1: number/* float */, y1: number/* float */,
+ x2: number/* float */, y2: number/* float */,
+ x3: number/* float */, y3: number/* float */
+ ): PerspectiveTransform {
+ // Here, the adjoint serves as the inverse:
+ return PerspectiveTransform.squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3).buildAdjoint();
+ }
+
+ protected buildAdjoint(): PerspectiveTransform {
+ // Adjoint is the transpose of the cofactor matrix:
+ return new PerspectiveTransform(
+ this.a22 * this.a33 - this.a23 * this.a32,
+ this.a23 * this.a31 - this.a21 * this.a33,
+ this.a21 * this.a32 - this.a22 * this.a31,
+ this.a13 * this.a32 - this.a12 * this.a33,
+ this.a11 * this.a33 - this.a13 * this.a31,
+ this.a12 * this.a31 - this.a11 * this.a32,
+ this.a12 * this.a23 - this.a13 * this.a22,
+ this.a13 * this.a21 - this.a11 * this.a23,
+ this.a11 * this.a22 - this.a12 * this.a21
+ );
+ }
+
+ protected times(other: PerspectiveTransform): PerspectiveTransform {
+ return new PerspectiveTransform(
+ this.a11 * other.a11 + this.a21 * other.a12 + this.a31 * other.a13,
+ this.a11 * other.a21 + this.a21 * other.a22 + this.a31 * other.a23,
+ this.a11 * other.a31 + this.a21 * other.a32 + this.a31 * other.a33,
+ this.a12 * other.a11 + this.a22 * other.a12 + this.a32 * other.a13,
+ this.a12 * other.a21 + this.a22 * other.a22 + this.a32 * other.a23,
+ this.a12 * other.a31 + this.a22 * other.a32 + this.a32 * other.a33,
+ this.a13 * other.a11 + this.a23 * other.a12 + this.a33 * other.a13,
+ this.a13 * other.a21 + this.a23 * other.a22 + this.a33 * other.a23,
+ this.a13 * other.a31 + this.a23 * other.a32 + this.a33 * other.a33
+ );
+ }
}
diff --git a/src/core/common/StringUtils.ts b/src/core/common/StringUtils.ts
index 70bff9e5..40cb481b 100644
--- a/src/core/common/StringUtils.ts
+++ b/src/core/common/StringUtils.ts
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common {*/
+/* namespace com.google.zxing.common { */
-/*import java.nio.charset.Charset;*/
-/*import java.util.Map;*/
+/* import java.nio.charset.Charset; */
+/* import java.util.Map; */
import DecodeHintType from '../DecodeHintType';
import CharacterSetECI from './CharacterSetECI';
@@ -57,7 +57,7 @@ export default class StringUtils {
* @return name of guessed encoding; at the moment will only guess one of:
* {@link #SHIFT_JIS}, {@link #UTF8}, {@link #ISO88591}, or the platform
* default encoding if none of these can possibly be correct
- */
+ */
public static guessEncoding(bytes: Uint8Array, hints: Map): string {
if (hints !== null && hints !== undefined && undefined !== hints.get(DecodeHintType.CHARACTER_SET)) {
return hints.get(DecodeHintType.CHARACTER_SET).toString();
@@ -86,9 +86,9 @@ export default class StringUtils {
let isoHighOther = 0;
const utf8bom = bytes.length > 3 &&
- bytes[0] === /*(byte) */0xEF &&
- bytes[1] === /*(byte) */0xBB &&
- bytes[2] === /*(byte) */0xBF;
+ bytes[0] === /* (byte) */0xEF &&
+ bytes[1] === /* (byte) */0xBB &&
+ bytes[2] === /* (byte) */0xBF;
for (let i = 0;
i < length && (canBeISO88591 || canBeShiftJIS || canBeUTF8);
@@ -224,7 +224,7 @@ export default class StringUtils {
*
* @param append The new string to append.
* @param args Argumets values to be formated.
- */
+ */
public static format(append: string, ...args: any[]) {
let i = -1;
@@ -265,21 +265,21 @@ export default class StringUtils {
/**
*
- */
+ */
public static getBytes(str: string, encoding: CharacterSetECI): Uint8Array {
return StringEncoding.encode(str, encoding);
}
/**
* Returns the charcode at the specified index or at index zero.
- */
+ */
public static getCharCode(str: string, index = 0): int {
return str.charCodeAt(index);
}
/**
* Returns char for given charcode
- */
+ */
public static getCharAt(charCode: number): string {
return String.fromCharCode(charCode);
}
diff --git a/src/core/common/detector/CornerDetector.ts b/src/core/common/detector/CornerDetector.ts
index b7e1da7b..9ca22a88 100644
--- a/src/core/common/detector/CornerDetector.ts
+++ b/src/core/common/detector/CornerDetector.ts
@@ -23,269 +23,269 @@ import NotFoundException from '../../NotFoundException';
*/
export default class CornerDetector {
- private image: BitMatrix;
- private height: number;
- private width: number;
- private leftInit: number;
- private rightInit: number;
- private downInit: number;
- private upInit: number;
- private targetMatrixSize: number;
-
-
- /**
- * @throws NotFoundException if image is too small to accommodate {@code initSize}
- */
- public constructor(image: BitMatrix, initSize: number, x: number, y: number, targetMatrixSize: number) {
- this.image = image;
- this.height = image.getHeight();
- this.width = image.getWidth();
- const halfsize = initSize / 2;
- this.leftInit = x - halfsize;
- this.rightInit = x + halfsize;
- this.upInit = y - halfsize;
- this.downInit = y + halfsize;
- this.targetMatrixSize = targetMatrixSize * 2;
- if (this.upInit < 0 || this.leftInit < 0 || this.downInit >= this.height || this.rightInit >= this.width) {
- throw new NotFoundException();
- }
+ private image: BitMatrix;
+ private height: number;
+ private width: number;
+ private leftInit: number;
+ private rightInit: number;
+ private downInit: number;
+ private upInit: number;
+ private targetMatrixSize: number;
+
+
+ /**
+ * @throws NotFoundException if image is too small to accommodate {@code initSize}
+ */
+ public constructor(image: BitMatrix, initSize: number, x: number, y: number, targetMatrixSize: number) {
+ this.image = image;
+ this.height = image.getHeight();
+ this.width = image.getWidth();
+ const halfsize = initSize / 2;
+ this.leftInit = x - halfsize;
+ this.rightInit = x + halfsize;
+ this.upInit = y - halfsize;
+ this.downInit = y + halfsize;
+ this.targetMatrixSize = targetMatrixSize * 2;
+ if (this.upInit < 0 || this.leftInit < 0 || this.downInit >= this.height || this.rightInit >= this.width) {
+ throw new NotFoundException();
}
+ }
- /**
- * @throws NotFoundException if no Data Matrix Code can be found
- */
- public detect(): ResultPoint[] {
-
- let left = this.leftInit;
- let right = this.rightInit;
- let up = this.upInit;
- let down = this.downInit;
- let sizeExceeded = false;
- let aBlackPointFoundOnBorder = true;
- let atLeastOneBlackPointFoundOnBorder = false;
-
- let atLeastOneBlackPointFoundOnRight = false;
- let atLeastOneBlackPointFoundOnBottom = false;
- let atLeastOneBlackPointFoundOnLeft = false;
- let atLeastOneBlackPointFoundOnTop = false;
-
- while (aBlackPointFoundOnBorder) {
-
- aBlackPointFoundOnBorder = false;
-
- // .....
- // . |
- // .....
- let rightBorderNotWhite = true;
- while ((rightBorderNotWhite || !atLeastOneBlackPointFoundOnRight) && right < this.width) {
- rightBorderNotWhite = this.containsBlackPoint(up, down, right, false);
- if (rightBorderNotWhite) {
- right++;
- aBlackPointFoundOnBorder = true;
- atLeastOneBlackPointFoundOnRight = true;
- } else if (!atLeastOneBlackPointFoundOnRight) {
- right++;
- }
- }
-
- if (right >= this.width) {
- sizeExceeded = true;
- break;
- }
-
- // .....
- // . .
- // .___.
- let bottomBorderNotWhite = true;
- while ((bottomBorderNotWhite || !atLeastOneBlackPointFoundOnBottom) && down < this.height) {
- bottomBorderNotWhite = this.containsBlackPoint(left, right, down, true);
- if (bottomBorderNotWhite) {
- down++;
- aBlackPointFoundOnBorder = true;
- atLeastOneBlackPointFoundOnBottom = true;
- } else if (!atLeastOneBlackPointFoundOnBottom) {
- down++;
- }
- }
-
- if (down >= this.height) {
- sizeExceeded = true;
- break;
- }
-
- // .....
- // | .
- // .....
- let leftBorderNotWhite = true;
- while ((leftBorderNotWhite || !atLeastOneBlackPointFoundOnLeft) && left >= 0) {
- leftBorderNotWhite = this.containsBlackPoint(up, down, left, false);
- if (leftBorderNotWhite) {
- left--;
- aBlackPointFoundOnBorder = true;
- atLeastOneBlackPointFoundOnLeft = true;
- } else if (!atLeastOneBlackPointFoundOnLeft) {
- left--;
- }
- }
+ /**
+ * @throws NotFoundException if no Data Matrix Code can be found
+ */
+ public detect(): ResultPoint[] {
+
+ let left = this.leftInit;
+ let right = this.rightInit;
+ let up = this.upInit;
+ let down = this.downInit;
+ let sizeExceeded = false;
+ let aBlackPointFoundOnBorder = true;
+ let atLeastOneBlackPointFoundOnBorder = false;
+
+ let atLeastOneBlackPointFoundOnRight = false;
+ let atLeastOneBlackPointFoundOnBottom = false;
+ let atLeastOneBlackPointFoundOnLeft = false;
+ let atLeastOneBlackPointFoundOnTop = false;
+
+ while (aBlackPointFoundOnBorder) {
+
+ aBlackPointFoundOnBorder = false;
+
+ // .....
+ // . |
+ // .....
+ let rightBorderNotWhite = true;
+ while ((rightBorderNotWhite || !atLeastOneBlackPointFoundOnRight) && right < this.width) {
+ rightBorderNotWhite = this.containsBlackPoint(up, down, right, false);
+ if (rightBorderNotWhite) {
+ right++;
+ aBlackPointFoundOnBorder = true;
+ atLeastOneBlackPointFoundOnRight = true;
+ } else if (!atLeastOneBlackPointFoundOnRight) {
+ right++;
+ }
+ }
+
+ if (right >= this.width) {
+ sizeExceeded = true;
+ break;
+ }
+
+ // .....
+ // . .
+ // .___.
+ let bottomBorderNotWhite = true;
+ while ((bottomBorderNotWhite || !atLeastOneBlackPointFoundOnBottom) && down < this.height) {
+ bottomBorderNotWhite = this.containsBlackPoint(left, right, down, true);
+ if (bottomBorderNotWhite) {
+ down++;
+ aBlackPointFoundOnBorder = true;
+ atLeastOneBlackPointFoundOnBottom = true;
+ } else if (!atLeastOneBlackPointFoundOnBottom) {
+ down++;
+ }
+ }
+
+ if (down >= this.height) {
+ sizeExceeded = true;
+ break;
+ }
+
+ // .....
+ // | .
+ // .....
+ let leftBorderNotWhite = true;
+ while ((leftBorderNotWhite || !atLeastOneBlackPointFoundOnLeft) && left >= 0) {
+ leftBorderNotWhite = this.containsBlackPoint(up, down, left, false);
+ if (leftBorderNotWhite) {
+ left--;
+ aBlackPointFoundOnBorder = true;
+ atLeastOneBlackPointFoundOnLeft = true;
+ } else if (!atLeastOneBlackPointFoundOnLeft) {
+ left--;
+ }
+ }
+
+ if (left < 0) {
+ sizeExceeded = true;
+ break;
+ }
+
+ // .___.
+ // . .
+ // .....
+ let topBorderNotWhite = true;
+ while ((topBorderNotWhite || !atLeastOneBlackPointFoundOnTop) && up >= 0) {
+ topBorderNotWhite = this.containsBlackPoint(left, right, up, true);
+ if (topBorderNotWhite) {
+ up--;
+ aBlackPointFoundOnBorder = true;
+ atLeastOneBlackPointFoundOnTop = true;
+ } else if (!atLeastOneBlackPointFoundOnTop) {
+ up--;
+ }
+ }
- if (left < 0) {
- sizeExceeded = true;
- break;
- }
+ if (up < 0) {
+ sizeExceeded = true;
+ break;
+ }
- // .___.
- // . .
- // .....
- let topBorderNotWhite = true;
- while ((topBorderNotWhite || !atLeastOneBlackPointFoundOnTop) && up >= 0) {
- topBorderNotWhite = this.containsBlackPoint(left, right, up, true);
- if (topBorderNotWhite) {
- up--;
- aBlackPointFoundOnBorder = true;
- atLeastOneBlackPointFoundOnTop = true;
- } else if (!atLeastOneBlackPointFoundOnTop) {
- up--;
- }
- }
+ if (aBlackPointFoundOnBorder) {
+ atLeastOneBlackPointFoundOnBorder = true;
+ }
+ }
- if (up < 0) {
- sizeExceeded = true;
- break;
+ if (!sizeExceeded && atLeastOneBlackPointFoundOnBorder) {
+ return this.findCorners(right, left, down, up);
+ } else {
+ throw new NotFoundException();
+ }
+ }
+
+ private findCorners(right: number, left: number, down: number, up: number): ResultPoint[] {
+ //
+ // A------------ ------------B
+ // | | up | |
+ // | -------|--------------|------- |
+ // | | | | | |
+ // | | | | | |
+ // ------------AP BP------------
+ // | |
+ // | |
+ // left | | right
+ // | |
+ // | |
+ // ------------DP CP------------
+ // | | | | | |
+ // | | | down | | |
+ // | -------|-------------|-------- |
+ // | | | |
+ // D-----------| |------------C
+ //
+
+
+ const width = right - left;
+ const height = down - up;
+ const sampler = 16 / this.targetMatrixSize;
+ const sampler2 = 4 / this.targetMatrixSize;
+ const deltaX = width * sampler2;
+ const deltaY = height * sampler2;
+ const areaWidth = deltaX + (right - left) * sampler;
+ const areaHeight = deltaY + (down - up) * sampler;
+
+ const a = new ResultPoint(left - deltaX, up - deltaY);
+ const b = new ResultPoint(right + deltaX, up - deltaY);
+ const c = new ResultPoint(right + deltaX, down + deltaY);
+ const d = new ResultPoint(left - deltaX, down + deltaY);
+
+ const ap = new ResultPoint(a.getX() + areaWidth, a.getY() + areaHeight);
+ const bp = new ResultPoint(b.getX() - areaWidth, b.getY() + areaHeight);
+ const cp = new ResultPoint(c.getX() - areaWidth, c.getY() - areaHeight);
+ const dp = new ResultPoint(d.getX() + areaWidth, d.getY() - areaHeight);
+
+ const topLeftCorner = this.getCornerFromArea(a.getX(), ap.getX(), a.getY(), ap.getY(), false, false);
+ const topRightCorner = this.getCornerFromArea(bp.getX(), b.getX(), b.getY(), bp.getY(), true, false);
+ const bottomRightCorner = this.getCornerFromArea(cp.getX(), c.getX(), cp.getY(), c.getY(), true, true);
+ const bottomLeftCorner = this.getCornerFromArea(d.getX(), dp.getX(), dp.getY(), d.getY(), false, true);
+
+ const xCorrection = (topRightCorner.getX() - topLeftCorner.getX()) / this.targetMatrixSize;
+ const yCorrection = (bottomRightCorner.getY() - topRightCorner.getY()) / this.targetMatrixSize;
+
+ const topLeftCornerCenter = new ResultPoint(topLeftCorner.getX() + xCorrection, topLeftCorner.getY() + yCorrection);
+ const topRightCornerCenter = new ResultPoint(topRightCorner.getX() - xCorrection, topRightCorner.getY() + yCorrection);
+ const bottomRightCornerCenter = new ResultPoint(bottomRightCorner.getX() - xCorrection, bottomRightCorner.getY() - yCorrection);
+ const bottomLeftCornerCenter = new ResultPoint(bottomLeftCorner.getX() + xCorrection, bottomLeftCorner.getY() - yCorrection);
+
+ const result: ResultPoint[] = [topLeftCornerCenter, topRightCornerCenter, bottomRightCornerCenter, bottomLeftCornerCenter];
+ return result;
+ }
+
+ private getCornerFromArea(left: number, right: number, top: number, bottom: number, maximizeX: boolean, maximizeY: boolean): ResultPoint {
+ let resX = maximizeX ? 0 : Number.MAX_VALUE;
+ let resY = maximizeY ? 0 : Number.MAX_VALUE;
+ for (let x = left; x < right; x++) {
+ for (let y = top; y < bottom; y++) {
+ if (x > 0 && y > 0 && x < this.image.getWidth() && y < this.image.getHeight()) {
+ if (this.image.get(x, y)) {
+ if (maximizeX) {
+ if (x > resX) {
+ resX = x;
+ }
+ } else {
+ if (x < resX) {
+ resX = x;
+ }
}
-
- if (aBlackPointFoundOnBorder) {
- atLeastOneBlackPointFoundOnBorder = true;
+ if (maximizeY) {
+ if (y > resY) {
+ resY = y;
+ }
+ } else {
+ if (y < resY) {
+ resY = y;
+ }
}
+ }
}
-
- if (!sizeExceeded && atLeastOneBlackPointFoundOnBorder) {
- return this.findCorners(right, left, down, up);
- } else {
- throw new NotFoundException();
- }
+ }
}
-
- private findCorners(right: number, left: number, down: number, up: number): ResultPoint[] {
- //
- // A------------ ------------B
- // | | up | |
- // | -------|--------------|------- |
- // | | | | | |
- // | | | | | |
- // ------------AP BP------------
- // | |
- // | |
- // left | | right
- // | |
- // | |
- // ------------DP CP------------
- // | | | | | |
- // | | | down | | |
- // | -------|-------------|-------- |
- // | | | |
- // D-----------| |------------C
- //
-
-
- const width = right - left;
- const height = down - up;
- const sampler = 16 / this.targetMatrixSize;
- const sampler2 = 4 / this.targetMatrixSize;
- const deltaX = width * sampler2;
- const deltaY = height * sampler2;
- const areaWidth = deltaX + (right - left) * sampler;
- const areaHeight = deltaY + (down - up) * sampler;
-
- const a = new ResultPoint(left - deltaX, up - deltaY);
- const b = new ResultPoint(right + deltaX, up - deltaY);
- const c = new ResultPoint(right + deltaX, down + deltaY);
- const d = new ResultPoint(left - deltaX, down + deltaY);
-
- const ap = new ResultPoint(a.getX() + areaWidth, a.getY() + areaHeight);
- const bp = new ResultPoint(b.getX() - areaWidth, b.getY() + areaHeight);
- const cp = new ResultPoint(c.getX() - areaWidth, c.getY() - areaHeight);
- const dp = new ResultPoint(d.getX() + areaWidth, d.getY() - areaHeight);
-
- const topLeftCorner = this.getCornerFromArea(a.getX(), ap.getX(), a.getY(), ap.getY(), false, false);
- const topRightCorner = this.getCornerFromArea(bp.getX(), b.getX(), b.getY(), bp.getY(), true, false);
- const bottomRightCorner = this.getCornerFromArea(cp.getX(), c.getX(), cp.getY(), c.getY(), true, true);
- const bottomLeftCorner = this.getCornerFromArea(d.getX(), dp.getX(), dp.getY(), d.getY(), false, true);
-
- const xCorrection = (topRightCorner.getX() - topLeftCorner.getX()) / this.targetMatrixSize;
- const yCorrection = (bottomRightCorner.getY() - topRightCorner.getY()) / this.targetMatrixSize;
-
- const topLeftCornerCenter = new ResultPoint(topLeftCorner.getX() + xCorrection, topLeftCorner.getY() + yCorrection);
- const topRightCornerCenter = new ResultPoint(topRightCorner.getX() - xCorrection, topRightCorner.getY() + yCorrection);
- const bottomRightCornerCenter = new ResultPoint(bottomRightCorner.getX() - xCorrection, bottomRightCorner.getY() - yCorrection);
- const bottomLeftCornerCenter = new ResultPoint(bottomLeftCorner.getX() + xCorrection, bottomLeftCorner.getY() - yCorrection);
-
- const result: ResultPoint[] = [topLeftCornerCenter, topRightCornerCenter, bottomRightCornerCenter, bottomLeftCornerCenter];
- return result;
+ if (resX === 0 || resY === 0) {
+ throw new NotFoundException();
+ } else {
+ return new ResultPoint(resX, resY);
}
+ }
- private getCornerFromArea(left: number, right: number, top: number, bottom: number, maximizeX: boolean, maximizeY: boolean): ResultPoint {
- let resX = maximizeX ? 0 : Number.MAX_VALUE;
- let resY = maximizeY ? 0 : Number.MAX_VALUE;
- for (let x = left; x < right; x++) {
- for (let y = top; y < bottom; y++) {
- if (x > 0 && y > 0 && x < this.image.getWidth() && y < this.image.getHeight()) {
- if (this.image.get(x, y)) {
- if (maximizeX) {
- if (x > resX) {
- resX = x;
- }
- } else {
- if (x < resX) {
- resX = x;
- }
- }
- if (maximizeY) {
- if (y > resY) {
- resY = y;
- }
- } else {
- if (y < resY) {
- resY = y;
- }
- }
- }
- }
- }
- }
- if (resX === 0 || resY === 0) {
- throw new NotFoundException();
- } else {
- return new ResultPoint(resX, resY);
- }
- }
+ /**
+ * Determines whether a segment contains a black point
+ *
+ * @param a min value of the scanned coordinate
+ * @param b max value of the scanned coordinate
+ * @param fixed value of fixed coordinate
+ * @param horizontal set to true if scan must be horizontal, false if vertical
+ * @return true if a black point has been found, else false.
+ */
+ private containsBlackPoint(a: number, b: number, fixed: number, horizontal: boolean): boolean {
- /**
- * Determines whether a segment contains a black point
- *
- * @param a min value of the scanned coordinate
- * @param b max value of the scanned coordinate
- * @param fixed value of fixed coordinate
- * @param horizontal set to true if scan must be horizontal, false if vertical
- * @return true if a black point has been found, else false.
- */
- private containsBlackPoint(a: number, b: number, fixed: number, horizontal: boolean): boolean {
-
- if (horizontal) {
- for (let x = a; x <= b; x++) {
- if (this.image.get(x, fixed)) {
- return true;
- }
- }
- } else {
- for (let y = a; y <= b; y++) {
- if (this.image.get(fixed, y)) {
- return true;
- }
- }
+ if (horizontal) {
+ for (let x = a; x <= b; x++) {
+ if (this.image.get(x, fixed)) {
+ return true;
}
-
- return false;
+ }
+ } else {
+ for (let y = a; y <= b; y++) {
+ if (this.image.get(fixed, y)) {
+ return true;
+ }
+ }
}
+ return false;
+ }
+
}
diff --git a/src/core/common/detector/MathUtils.ts b/src/core/common/detector/MathUtils.ts
index bf167c13..ebd47451 100644
--- a/src/core/common/detector/MathUtils.ts
+++ b/src/core/common/detector/MathUtils.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common.detector {*/
+/* namespace com.google.zxing.common.detector { */
/**
* General math-related and numeric utility functions.
@@ -31,12 +31,12 @@ export default class MathUtils {
*
* @param d real value to round
* @return nearest {@code int}
- */
- public static round(d: number/*float*/): number /*int*/ {
+ */
+ public static round(d: number/* float */): number /* int */ {
if (NaN === d) return 0;
if (d <= Number.MIN_SAFE_INTEGER) return Number.MIN_SAFE_INTEGER;
if (d >= Number.MAX_SAFE_INTEGER) return Number.MAX_SAFE_INTEGER;
- return /*(int) */(d + (d < 0.0 ? -0.5 : 0.5)) | 0;
+ return /* (int) */(d + (d < 0.0 ? -0.5 : 0.5)) | 0;
}
// TYPESCRIPTPORT: maybe remove round method and call directly Math.round, it looks like it doesn't make sense for js
@@ -46,11 +46,11 @@ export default class MathUtils {
* @param bX point B x coordinate
* @param bY point B y coordinate
* @return Euclidean distance between points A and B
- */
- public static distance(aX: number/*float|int*/, aY: number/*float|int*/, bX: number/*float|int*/, bY: number/*float|int*/): number/*float*/ {
+ */
+ public static distance(aX: number/* float|int */, aY: number/* float|int */, bX: number/* float|int */, bY: number/* float|int */): number/* float */ {
const xDiff = aX - bX;
const yDiff = aY - bY;
- return /*(float) */Math.sqrt(xDiff * xDiff + yDiff * yDiff);
+ return /* (float) */Math.sqrt(xDiff * xDiff + yDiff * yDiff);
}
/**
@@ -59,8 +59,8 @@ export default class MathUtils {
* @param bX point B x coordinate
* @param bY point B y coordinate
* @return Euclidean distance between points A and B
- */
- // public static distance(aX: number /*int*/, aY: number /*int*/, bX: number /*int*/, bY: number /*int*/): float {
+ */
+ // public static distance(aX: number /*int */, aY: number /*int */, bX: number /*int */, bY: number /*int */): float {
// const xDiff = aX - bX
// const yDiff = aY - bY
// return (float) Math.sqrt(xDiff * xDiff + yDiff * yDiff);
@@ -69,8 +69,8 @@ export default class MathUtils {
/**
* @param array values to sum
* @return sum of values in array
- */
- public static sum(array: Int32Array): number /*int*/ {
+ */
+ public static sum(array: Int32Array): number /* int */ {
let count = 0;
for (let i = 0, length = array.length; i !== length; i++) {
const a = array[i];
diff --git a/src/core/common/detector/MonochromeRectangleDetector.ts b/src/core/common/detector/MonochromeRectangleDetector.ts
index c6d68e0b..0b87bb72 100644
--- a/src/core/common/detector/MonochromeRectangleDetector.ts
+++ b/src/core/common/detector/MonochromeRectangleDetector.ts
@@ -12,9 +12,9 @@
// * 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.
-// */
+// */
-// /*namespace com.google.zxing.common.detector {*/
+// /*namespace com.google.zxing.common.detector { */
// import ResultPoint from '../../ResultPoint'
// import BitMatrix from '../BitMatrix'
@@ -26,7 +26,7 @@
// *
// * @author Sean Owen
// * @deprecated without replacement since 3.3.0
-// */
+// */
// @Deprecated
// export default class MonochromeRectangleDetector {
@@ -47,10 +47,10 @@
// * the topmost point and the last, the bottommost. The second point will be leftmost and the
// * third, the rightmost
// * @throws NotFoundException if no Data Matrix Code can be found
-// */
-// public detect(): ResultPoInt32Array /*throws NotFoundException*/ {
-// height: number /*int*/ = image.getHeight();
-// width: number /*int*/ = image.getWidth();
+// */
+// public detect(): ResultPoInt32Array /*throws NotFoundException */ {
+// height: number /*int */ = image.getHeight();
+// width: number /*int */ = image.getWidth();
// const halfHeight = height / 2
// const halfWidth = width / 2
// const deltaY = Math.max(1, height / (MAX_MODULES * 8));
@@ -97,16 +97,16 @@
// * the barcode
// * @return a {@link ResultPoint} encapsulating the corner that was found
// * @throws NotFoundException if such a point cannot be found
-// */
-// private ResultPoint findCornerFromCenter(centerX: number /*int*/,
-// deltaX: number /*int*/,
-// left: number /*int*/,
-// right: number /*int*/,
-// centerY: number /*int*/,
-// deltaY: number /*int*/,
-// top: number /*int*/,
-// bottom: number /*int*/,
-// maxWhiteRun: number /*int*/) /*throws NotFoundException*/ {
+// */
+// private ResultPoint findCornerFromCenter(centerX: number /*int */,
+// deltaX: number /*int */,
+// left: number /*int */,
+// right: number /*int */,
+// centerY: number /*int */,
+// deltaY: number /*int */,
+// top: number /*int */,
+// bottom: number /*int */,
+// maxWhiteRun: number /*int */) /*throws NotFoundException */ {
// const lastRange: Int32Array = null
// for (let y = centerY, x = centerX
// y < bottom && y >= top && x < right && x >= left
@@ -165,8 +165,8 @@
// * @param horizontal if true, we're scanning left-right, instead of up-down
// * @return const with: Int32Array start and end of found range, or null if no such range is found
// * (e.g. only white was found)
-// */
-// private const blackWhiteRange: Int32Array(fixedDimension: number /*int*/, maxWhiteRun: number /*int*/, minDim: number /*int*/, maxDim: number /*int*/, boolean horizontal) {
+// */
+// private const blackWhiteRange: Int32Array(fixedDimension: number /*int */, maxWhiteRun: number /*int */, minDim: number /*int */, maxDim: number /*int */, boolean horizontal) {
// const center = (minDim + maxDim) / 2
@@ -213,4 +213,4 @@
// return end > start ? new Int32Array{start, end} : null
// }
-// }
\ No newline at end of file
+// }
diff --git a/src/core/common/detector/WhiteRectangleDetector.ts b/src/core/common/detector/WhiteRectangleDetector.ts
index 8e675379..274c6c08 100644
--- a/src/core/common/detector/WhiteRectangleDetector.ts
+++ b/src/core/common/detector/WhiteRectangleDetector.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common.detector {*/
+/* namespace com.google.zxing.common.detector { */
import ResultPoint from '../../ResultPoint';
import BitMatrix from '../BitMatrix';
@@ -34,314 +34,314 @@ import NotFoundException from '../../NotFoundException';
*/
export default class WhiteRectangleDetector {
- private static INIT_SIZE = 10;
- private static CORR = 1;
-
- private height: number; /*int*/
- private width: number; /*int*/
- private leftInit: number; /*int*/
- private rightInit: number; /*int*/
- private downInit: number; /*int*/
- private upInit: number; /*int*/
-
- // public constructor(private image: BitMatrix) /*throws NotFoundException*/ {
- // this(image, INIT_SIZE, image.getWidth() / 2, image.getHeight() / 2)
- // }
-
- /**
- * @param image barcode image to find a rectangle in
- * @param initSize initial size of search area around center
- * @param x x position of search center
- * @param y y position of search center
- * @throws NotFoundException if image is too small to accommodate {@code initSize}
- */
- public constructor(private image: BitMatrix, initSize?: number /*int*/, x?: number /*int*/, y?: number /*int*/) /*throws NotFoundException*/ {
- this.height = image.getHeight();
- this.width = image.getWidth();
- if (undefined === initSize || null === initSize) {
- initSize = WhiteRectangleDetector.INIT_SIZE;
+ private static INIT_SIZE = 10;
+ private static CORR = 1;
+
+ private height: number; /* int */
+ private width: number; /* int */
+ private leftInit: number; /* int */
+ private rightInit: number; /* int */
+ private downInit: number; /* int */
+ private upInit: number; /* int */
+
+ // public constructor(private image: BitMatrix) /*throws NotFoundException */ {
+ // this(image, INIT_SIZE, image.getWidth() / 2, image.getHeight() / 2)
+ // }
+
+ /**
+ * @param image barcode image to find a rectangle in
+ * @param initSize initial size of search area around center
+ * @param x x position of search center
+ * @param y y position of search center
+ * @throws NotFoundException if image is too small to accommodate {@code initSize}
+ */
+ public constructor(private image: BitMatrix, initSize?: number /* int */, x?: number /* int */, y?: number /* int */) /* throws NotFoundException */ {
+ this.height = image.getHeight();
+ this.width = image.getWidth();
+ if (undefined === initSize || null === initSize) {
+ initSize = WhiteRectangleDetector.INIT_SIZE;
+ }
+ if (undefined === x || null === x) {
+ x = image.getWidth() / 2 | 0;
+ }
+ if (undefined === y || null === y) {
+ y = image.getHeight() / 2 | 0;
+ }
+ const halfsize = initSize / 2 | 0;
+ this.leftInit = x - halfsize;
+ this.rightInit = x + halfsize;
+ this.upInit = y - halfsize;
+ this.downInit = y + halfsize;
+ if (this.upInit < 0 || this.leftInit < 0 || this.downInit >= this.height || this.rightInit >= this.width) {
+ throw new NotFoundException();
+ }
+ }
+
+ /**
+ *
+ * Detects a candidate barcode-like rectangular region within an image. It
+ * starts around the center of the image, increases the size of the candidate
+ * region until it finds a white rectangular region.
+ *
+ *
+ * @return {@link ResultPoint}[] describing the corners of the rectangular
+ * region. The first and last points are opposed on the diagonal, as
+ * are the second and third. The first point will be the topmost
+ * point and the last, the bottommost. The second point will be
+ * leftmost and the third, the rightmost
+ * @throws NotFoundException if no Data Matrix Code can be found
+ */
+ public detect(): Array /* throws NotFoundException */ {
+ let left = this.leftInit;
+ let right = this.rightInit;
+ let up = this.upInit;
+ let down = this.downInit;
+ let sizeExceeded: boolean = false;
+ let aBlackPointFoundOnBorder: boolean = true;
+ let atLeastOneBlackPointFoundOnBorder: boolean = false;
+
+ let atLeastOneBlackPointFoundOnRight: boolean = false;
+ let atLeastOneBlackPointFoundOnBottom: boolean = false;
+ let atLeastOneBlackPointFoundOnLeft: boolean = false;
+ let atLeastOneBlackPointFoundOnTop: boolean = false;
+
+ const width = this.width;
+ const height = this.height;
+
+ while (aBlackPointFoundOnBorder) {
+
+ aBlackPointFoundOnBorder = false;
+
+ // .....
+ // . |
+ // .....
+ let rightBorderNotWhite: boolean = true;
+ while ((rightBorderNotWhite || !atLeastOneBlackPointFoundOnRight) && right < width) {
+ rightBorderNotWhite = this.containsBlackPoint(up, down, right, false);
+ if (rightBorderNotWhite) {
+ right++;
+ aBlackPointFoundOnBorder = true;
+ atLeastOneBlackPointFoundOnRight = true;
+ } else if (!atLeastOneBlackPointFoundOnRight) {
+ right++;
}
- if (undefined === x || null === x) {
- x = image.getWidth() / 2 | 0;
+ }
+
+ if (right >= width) {
+ sizeExceeded = true;
+ break;
+ }
+
+ // .....
+ // . .
+ // .___.
+ let bottomBorderNotWhite: boolean = true;
+ while ((bottomBorderNotWhite || !atLeastOneBlackPointFoundOnBottom) && down < height) {
+ bottomBorderNotWhite = this.containsBlackPoint(left, right, down, true);
+ if (bottomBorderNotWhite) {
+ down++;
+ aBlackPointFoundOnBorder = true;
+ atLeastOneBlackPointFoundOnBottom = true;
+ } else if (!atLeastOneBlackPointFoundOnBottom) {
+ down++;
}
- if (undefined === y || null === y) {
- y = image.getHeight() / 2 | 0;
+ }
+
+ if (down >= height) {
+ sizeExceeded = true;
+ break;
+ }
+
+ // .....
+ // | .
+ // .....
+ let leftBorderNotWhite: boolean = true;
+ while ((leftBorderNotWhite || !atLeastOneBlackPointFoundOnLeft) && left >= 0) {
+ leftBorderNotWhite = this.containsBlackPoint(up, down, left, false);
+ if (leftBorderNotWhite) {
+ left--;
+ aBlackPointFoundOnBorder = true;
+ atLeastOneBlackPointFoundOnLeft = true;
+ } else if (!atLeastOneBlackPointFoundOnLeft) {
+ left--;
}
- const halfsize = initSize / 2 | 0;
- this.leftInit = x - halfsize;
- this.rightInit = x + halfsize;
- this.upInit = y - halfsize;
- this.downInit = y + halfsize;
- if (this.upInit < 0 || this.leftInit < 0 || this.downInit >= this.height || this.rightInit >= this.width) {
- throw new NotFoundException();
+ }
+
+ if (left < 0) {
+ sizeExceeded = true;
+ break;
+ }
+
+ // .___.
+ // . .
+ // .....
+ let topBorderNotWhite: boolean = true;
+ while ((topBorderNotWhite || !atLeastOneBlackPointFoundOnTop) && up >= 0) {
+ topBorderNotWhite = this.containsBlackPoint(left, right, up, true);
+ if (topBorderNotWhite) {
+ up--;
+ aBlackPointFoundOnBorder = true;
+ atLeastOneBlackPointFoundOnTop = true;
+ } else if (!atLeastOneBlackPointFoundOnTop) {
+ up--;
}
- }
+ }
- /**
- *
- * Detects a candidate barcode-like rectangular region within an image. It
- * starts around the center of the image, increases the size of the candidate
- * region until it finds a white rectangular region.
- *
- *
- * @return {@link ResultPoint}[] describing the corners of the rectangular
- * region. The first and last points are opposed on the diagonal, as
- * are the second and third. The first point will be the topmost
- * point and the last, the bottommost. The second point will be
- * leftmost and the third, the rightmost
- * @throws NotFoundException if no Data Matrix Code can be found
- */
- public detect(): Array /*throws NotFoundException*/ {
- let left = this.leftInit;
- let right = this.rightInit;
- let up = this.upInit;
- let down = this.downInit;
- let sizeExceeded: boolean = false;
- let aBlackPointFoundOnBorder: boolean = true;
- let atLeastOneBlackPointFoundOnBorder: boolean = false;
-
- let atLeastOneBlackPointFoundOnRight: boolean = false;
- let atLeastOneBlackPointFoundOnBottom: boolean = false;
- let atLeastOneBlackPointFoundOnLeft: boolean = false;
- let atLeastOneBlackPointFoundOnTop: boolean = false;
-
- const width = this.width;
- const height = this.height;
-
- while (aBlackPointFoundOnBorder) {
-
- aBlackPointFoundOnBorder = false;
-
- // .....
- // . |
- // .....
- let rightBorderNotWhite: boolean = true;
- while ((rightBorderNotWhite || !atLeastOneBlackPointFoundOnRight) && right < width) {
- rightBorderNotWhite = this.containsBlackPoint(up, down, right, false);
- if (rightBorderNotWhite) {
- right++;
- aBlackPointFoundOnBorder = true;
- atLeastOneBlackPointFoundOnRight = true;
- } else if (!atLeastOneBlackPointFoundOnRight) {
- right++;
- }
- }
-
- if (right >= width) {
- sizeExceeded = true;
- break;
- }
-
- // .....
- // . .
- // .___.
- let bottomBorderNotWhite: boolean = true;
- while ((bottomBorderNotWhite || !atLeastOneBlackPointFoundOnBottom) && down < height) {
- bottomBorderNotWhite = this.containsBlackPoint(left, right, down, true);
- if (bottomBorderNotWhite) {
- down++;
- aBlackPointFoundOnBorder = true;
- atLeastOneBlackPointFoundOnBottom = true;
- } else if (!atLeastOneBlackPointFoundOnBottom) {
- down++;
- }
- }
-
- if (down >= height) {
- sizeExceeded = true;
- break;
- }
-
- // .....
- // | .
- // .....
- let leftBorderNotWhite: boolean = true;
- while ((leftBorderNotWhite || !atLeastOneBlackPointFoundOnLeft) && left >= 0) {
- leftBorderNotWhite = this.containsBlackPoint(up, down, left, false);
- if (leftBorderNotWhite) {
- left--;
- aBlackPointFoundOnBorder = true;
- atLeastOneBlackPointFoundOnLeft = true;
- } else if (!atLeastOneBlackPointFoundOnLeft) {
- left--;
- }
- }
-
- if (left < 0) {
- sizeExceeded = true;
- break;
- }
-
- // .___.
- // . .
- // .....
- let topBorderNotWhite: boolean = true;
- while ((topBorderNotWhite || !atLeastOneBlackPointFoundOnTop) && up >= 0) {
- topBorderNotWhite = this.containsBlackPoint(left, right, up, true);
- if (topBorderNotWhite) {
- up--;
- aBlackPointFoundOnBorder = true;
- atLeastOneBlackPointFoundOnTop = true;
- } else if (!atLeastOneBlackPointFoundOnTop) {
- up--;
- }
- }
-
- if (up < 0) {
- sizeExceeded = true;
- break;
- }
-
- if (aBlackPointFoundOnBorder) {
- atLeastOneBlackPointFoundOnBorder = true;
- }
+ if (up < 0) {
+ sizeExceeded = true;
+ break;
+ }
- }
+ if (aBlackPointFoundOnBorder) {
+ atLeastOneBlackPointFoundOnBorder = true;
+ }
- if (!sizeExceeded && atLeastOneBlackPointFoundOnBorder) {
+ }
- const maxSize = right - left;
+ if (!sizeExceeded && atLeastOneBlackPointFoundOnBorder) {
- let z: ResultPoint | null = null;
- for (let i = 1; z === null && i < maxSize; i++) {
- z = this.getBlackPointOnSegment(left, down - i, left + i, down);
- }
+ const maxSize = right - left;
- if (z == null) {
- throw new NotFoundException();
- }
+ let z: ResultPoint | null = null;
+ for (let i = 1; z === null && i < maxSize; i++) {
+ z = this.getBlackPointOnSegment(left, down - i, left + i, down);
+ }
- let t: ResultPoint | null = null;
- // go down right
- for (let i = 1; t === null && i < maxSize; i++) {
- t = this.getBlackPointOnSegment(left, up + i, left + i, up);
- }
+ if (z == null) {
+ throw new NotFoundException();
+ }
- if (t == null) {
- throw new NotFoundException();
- }
+ let t: ResultPoint | null = null;
+ // go down right
+ for (let i = 1; t === null && i < maxSize; i++) {
+ t = this.getBlackPointOnSegment(left, up + i, left + i, up);
+ }
- let x: ResultPoint | null = null;
- // go down left
- for (let i = 1; x === null && i < maxSize; i++) {
- x = this.getBlackPointOnSegment(right, up + i, right - i, up);
- }
+ if (t == null) {
+ throw new NotFoundException();
+ }
- if (x == null) {
- throw new NotFoundException();
- }
+ let x: ResultPoint | null = null;
+ // go down left
+ for (let i = 1; x === null && i < maxSize; i++) {
+ x = this.getBlackPointOnSegment(right, up + i, right - i, up);
+ }
- let y: ResultPoint | null = null;
- // go up left
- for (let i = 1; y === null && i < maxSize; i++) {
- y = this.getBlackPointOnSegment(right, down - i, right - i, down);
- }
+ if (x == null) {
+ throw new NotFoundException();
+ }
- if (y == null) {
- throw new NotFoundException();
- }
+ let y: ResultPoint | null = null;
+ // go up left
+ for (let i = 1; y === null && i < maxSize; i++) {
+ y = this.getBlackPointOnSegment(right, down - i, right - i, down);
+ }
- return this.centerEdges(y, z, x, t);
+ if (y == null) {
+ throw new NotFoundException();
+ }
- } else {
- throw new NotFoundException();
- }
+ return this.centerEdges(y, z, x, t);
+
+ } else {
+ throw new NotFoundException();
}
+ }
- private getBlackPointOnSegment(aX: number/*float*/, aY: number/*float*/, bX: number/*float*/, bY: number/*float*/): ResultPoint | null {
- const dist = MathUtils.round(MathUtils.distance(aX, aY, bX, bY));
- const xStep: number /*float*/ = (bX - aX) / dist;
- const yStep: number /*float*/ = (bY - aY) / dist;
+ private getBlackPointOnSegment(aX: number/* float */, aY: number/* float */, bX: number/* float */, bY: number/* float */): ResultPoint | null {
+ const dist = MathUtils.round(MathUtils.distance(aX, aY, bX, bY));
+ const xStep: number /* float */ = (bX - aX) / dist;
+ const yStep: number /* float */ = (bY - aY) / dist;
- const image = this.image;
+ const image = this.image;
- for (let i = 0; i < dist; i++) {
- const x = MathUtils.round(aX + i * xStep);
- const y = MathUtils.round(aY + i * yStep);
- if (image.get(x, y)) {
- return new ResultPoint(x, y);
- }
- }
- return null;
+ for (let i = 0; i < dist; i++) {
+ const x = MathUtils.round(aX + i * xStep);
+ const y = MathUtils.round(aY + i * yStep);
+ if (image.get(x, y)) {
+ return new ResultPoint(x, y);
+ }
}
-
- /**
- * recenters the points of a constant distance towards the center
- *
- * @param y bottom most point
- * @param z left most point
- * @param x right most point
- * @param t top most point
- * @return {@link ResultPoint}[] describing the corners of the rectangular
- * region. The first and last points are opposed on the diagonal, as
- * are the second and third. The first point will be the topmost
- * point and the last, the bottommost. The second point will be
- * leftmost and the third, the rightmost
- */
- private centerEdges(y: ResultPoint, z: ResultPoint,
- x: ResultPoint, t: ResultPoint): Array {
-
- //
- // t t
- // z x
- // x OR z
- // y y
- //
-
- const yi: number /*float*/ = y.getX();
- const yj: number /*float*/ = y.getY();
- const zi: number /*float*/ = z.getX();
- const zj: number /*float*/ = z.getY();
- const xi: number /*float*/ = x.getX();
- const xj: number /*float*/ = x.getY();
- const ti: number /*float*/ = t.getX();
- const tj: number /*float*/ = t.getY();
-
- const CORR = WhiteRectangleDetector.CORR;
-
- if (yi < this.width / 2.0) {
- return [
- new ResultPoint(ti - CORR, tj + CORR),
- new ResultPoint(zi + CORR, zj + CORR),
- new ResultPoint(xi - CORR, xj - CORR),
- new ResultPoint(yi + CORR, yj - CORR)];
- } else {
- return [
- new ResultPoint(ti + CORR, tj + CORR),
- new ResultPoint(zi + CORR, zj - CORR),
- new ResultPoint(xi - CORR, xj + CORR),
- new ResultPoint(yi - CORR, yj - CORR)];
- }
+ return null;
+ }
+
+ /**
+ * recenters the points of a constant distance towards the center
+ *
+ * @param y bottom most point
+ * @param z left most point
+ * @param x right most point
+ * @param t top most point
+ * @return {@link ResultPoint}[] describing the corners of the rectangular
+ * region. The first and last points are opposed on the diagonal, as
+ * are the second and third. The first point will be the topmost
+ * point and the last, the bottommost. The second point will be
+ * leftmost and the third, the rightmost
+ */
+ private centerEdges(y: ResultPoint, z: ResultPoint,
+ x: ResultPoint, t: ResultPoint): Array {
+
+ //
+ // t t
+ // z x
+ // x OR z
+ // y y
+ //
+
+ const yi: number /* float */ = y.getX();
+ const yj: number /* float */ = y.getY();
+ const zi: number /* float */ = z.getX();
+ const zj: number /* float */ = z.getY();
+ const xi: number /* float */ = x.getX();
+ const xj: number /* float */ = x.getY();
+ const ti: number /* float */ = t.getX();
+ const tj: number /* float */ = t.getY();
+
+ const CORR = WhiteRectangleDetector.CORR;
+
+ if (yi < this.width / 2.0) {
+ return [
+ new ResultPoint(ti - CORR, tj + CORR),
+ new ResultPoint(zi + CORR, zj + CORR),
+ new ResultPoint(xi - CORR, xj - CORR),
+ new ResultPoint(yi + CORR, yj - CORR)];
+ } else {
+ return [
+ new ResultPoint(ti + CORR, tj + CORR),
+ new ResultPoint(zi + CORR, zj - CORR),
+ new ResultPoint(xi - CORR, xj + CORR),
+ new ResultPoint(yi - CORR, yj - CORR)];
}
+ }
+
+ /**
+ * Determines whether a segment contains a black point
+ *
+ * @param a min value of the scanned coordinate
+ * @param b max value of the scanned coordinate
+ * @param fixed value of fixed coordinate
+ * @param horizontal set to true if scan must be horizontal, false if vertical
+ * @return true if a black point has been found, else false.
+ */
+ private containsBlackPoint(a: number /* int */, b: number /* int */, fixed: number /* int */, horizontal: boolean): boolean {
- /**
- * Determines whether a segment contains a black point
- *
- * @param a min value of the scanned coordinate
- * @param b max value of the scanned coordinate
- * @param fixed value of fixed coordinate
- * @param horizontal set to true if scan must be horizontal, false if vertical
- * @return true if a black point has been found, else false.
- */
- private containsBlackPoint(a: number /*int*/, b: number /*int*/, fixed: number /*int*/, horizontal: boolean): boolean {
-
- const image = this.image;
-
- if (horizontal) {
- for (let x = a; x <= b; x++) {
- if (image.get(x, fixed)) {
- return true;
- }
- }
- } else {
- for (let y = a; y <= b; y++) {
- if (image.get(fixed, y)) {
- return true;
- }
- }
- }
+ const image = this.image;
- return false;
+ if (horizontal) {
+ for (let x = a; x <= b; x++) {
+ if (image.get(x, fixed)) {
+ return true;
+ }
+ }
+ } else {
+ for (let y = a; y <= b; y++) {
+ if (image.get(fixed, y)) {
+ return true;
+ }
+ }
}
+ return false;
+ }
+
}
diff --git a/src/core/common/reedsolomon/AbstractGenericGF.ts b/src/core/common/reedsolomon/AbstractGenericGF.ts
index bca4a82e..3087493e 100644
--- a/src/core/common/reedsolomon/AbstractGenericGF.ts
+++ b/src/core/common/reedsolomon/AbstractGenericGF.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common.reedsolomon {*/
+/* namespace com.google.zxing.common.reedsolomon { */
// import GenericGFPoly from './GenericGFPoly';
@@ -39,24 +39,24 @@ export default abstract class AbstractGenericGF {
public abstract getZero(): any; // GenericGFPoly
public abstract buildMonomial(
- degree: number /*int*/,
- coefficient: number /*int*/
+ degree: number /* int */,
+ coefficient: number /* int */
): any; // GenericGFPoly
public abstract equals(o: Object): boolean;
- public abstract multiply(a: number /*int*/, b: number /*int*/): number;
- public abstract inverse(a: number /*int*/): number;
+ public abstract multiply(a: number /* int */, b: number /* int */): number;
+ public abstract inverse(a: number /* int */): number;
/**
* @return 2 to the power of a in GF(size)
- */
- public exp(a: number): number /*int*/ {
+ */
+ public exp(a: number): number /* int */ {
return this.expTable[a];
}
/**
* @return base 2 log of a in GF(size)
- */
- public log(a: number /*int*/): number /*int*/ {
+ */
+ public log(a: number /* int */): number /* int */ {
if (a === 0) {
throw new IllegalArgumentException();
}
@@ -67,11 +67,11 @@ export default abstract class AbstractGenericGF {
* Implements both addition and subtraction -- they are the same in GF(size).
*
* @return sum/difference of a and b
- */
+ */
public static addOrSubtract(
- a: number /*int*/,
- b: number /*int*/
- ): number /*int*/ {
+ a: number /* int */,
+ b: number /* int */
+ ): number /* int */ {
return a ^ b;
}
}
diff --git a/src/core/common/reedsolomon/AbstractGenericGFPoly.ts b/src/core/common/reedsolomon/AbstractGenericGFPoly.ts
index fb575e6a..cf1142b8 100644
--- a/src/core/common/reedsolomon/AbstractGenericGFPoly.ts
+++ b/src/core/common/reedsolomon/AbstractGenericGFPoly.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common.reedsolomon {*/
+/* namespace com.google.zxing.common.reedsolomon { */
// import GenericGF from './GenericGF';
import AbstractGenericGF from './AbstractGenericGF';
@@ -30,108 +30,108 @@ import AbstractGenericGF from './AbstractGenericGF';
*/
export default abstract class AbstractGenericGFPoly {
- protected field: AbstractGenericGF;
- protected coefficients: Int32Array;
+ protected field: AbstractGenericGF;
+ protected coefficients: Int32Array;
- public getCoefficients(): Int32Array {
- return this.coefficients;
- }
+ public getCoefficients(): Int32Array {
+ return this.coefficients;
+ }
- /**
- * @return degree of this polynomial
- */
- public getDegree(): number {
- return this.coefficients.length - 1;
- }
+ /**
+ * @return degree of this polynomial
+ */
+ public getDegree(): number {
+ return this.coefficients.length - 1;
+ }
- /**
- * @return true iff this polynomial is the monomial "0"
- */
- public isZero(): boolean {
- return this.coefficients[0] === 0;
- }
+ /**
+ * @return true iff this polynomial is the monomial "0"
+ */
+ public isZero(): boolean {
+ return this.coefficients[0] === 0;
+ }
- /**
- * @return coefficient of x^degree term in this polynomial
- */
- public getCoefficient(degree: number /*int*/): number {
- return this.coefficients[this.coefficients.length - 1 - degree];
+ /**
+ * @return coefficient of x^degree term in this polynomial
+ */
+ public getCoefficient(degree: number /* int */): number {
+ return this.coefficients[this.coefficients.length - 1 - degree];
+ }
+
+ /**
+ * @return evaluation of this polynomial at a given point
+ */
+ public evaluateAt(a: number /* int */): number {
+ if (a === 0) {
+ // Just return the x^0 coefficient
+ return this.getCoefficient(0);
+ }
+ const coefficients = this.coefficients;
+ let result: number;
+ if (a === 1) {
+ // Just the sum of the coefficients
+ result = 0;
+ for (let i = 0, length = coefficients.length; i !== length; i++) {
+ const coefficient = coefficients[i];
+ result = AbstractGenericGF.addOrSubtract(result, coefficient);
+ }
+ return result;
}
+ result = coefficients[0];
+ const size = coefficients.length;
+ const field = this.field;
+ for (let i = 1; i < size; i++) {
+ result = AbstractGenericGF.addOrSubtract(field.multiply(a, result), coefficients[i]);
+ }
+ return result;
+ }
- /**
- * @return evaluation of this polynomial at a given point
- */
- public evaluateAt(a: number /*int*/): number {
- if (a === 0) {
- // Just return the x^0 coefficient
- return this.getCoefficient(0);
- }
- const coefficients = this.coefficients;
- let result: number;
- if (a === 1) {
- // Just the sum of the coefficients
- result = 0;
- for (let i = 0, length = coefficients.length; i !== length; i++) {
- const coefficient = coefficients[i];
- result = AbstractGenericGF.addOrSubtract(result, coefficient);
- }
- return result;
+ public abstract addOrSubtract(other: AbstractGenericGFPoly): AbstractGenericGFPoly;
+
+ public abstract multiply(other: AbstractGenericGFPoly): AbstractGenericGFPoly;
+
+ public abstract multiplyScalar(scalar: number /* int */): AbstractGenericGFPoly;
+
+ public abstract multiplyByMonomial(degree: number /* int */, coefficient: number /* int */): AbstractGenericGFPoly;
+
+ public abstract divide(other: AbstractGenericGFPoly): AbstractGenericGFPoly[];
+
+ /* @Override */
+ public toString(): string {
+ let result = '';
+ for (let degree = this.getDegree(); degree >= 0; degree--) {
+ let coefficient = this.getCoefficient(degree);
+ if (coefficient !== 0) {
+ if (coefficient < 0) {
+ result += ' - ';
+ coefficient = -coefficient;
+ } else {
+ if (result.length > 0) {
+ result += ' + ';
+ }
}
- result = coefficients[0];
- const size = coefficients.length;
- const field = this.field;
- for (let i = 1; i < size; i++) {
- result = AbstractGenericGF.addOrSubtract(field.multiply(a, result), coefficients[i]);
+ if (degree === 0 || coefficient !== 1) {
+ const alphaPower = this.field.log(coefficient);
+ if (alphaPower === 0) {
+ result += '1';
+ } else if (alphaPower === 1) {
+ result += 'a';
+ } else {
+ result += 'a^';
+ result += alphaPower;
+ }
}
- return result;
- }
-
- public abstract addOrSubtract(other: AbstractGenericGFPoly): AbstractGenericGFPoly;
-
- public abstract multiply(other: AbstractGenericGFPoly): AbstractGenericGFPoly;
-
- public abstract multiplyScalar(scalar: number /*int*/): AbstractGenericGFPoly;
-
- public abstract multiplyByMonomial(degree: number /*int*/, coefficient: number /*int*/): AbstractGenericGFPoly;
-
- public abstract divide(other: AbstractGenericGFPoly): AbstractGenericGFPoly[];
-
- /*@Override*/
- public toString(): string {
- let result = '';
- for (let degree = this.getDegree(); degree >= 0; degree--) {
- let coefficient = this.getCoefficient(degree);
- if (coefficient !== 0) {
- if (coefficient < 0) {
- result += ' - ';
- coefficient = -coefficient;
- } else {
- if (result.length > 0) {
- result += ' + ';
- }
- }
- if (degree === 0 || coefficient !== 1) {
- const alphaPower = this.field.log(coefficient);
- if (alphaPower === 0) {
- result += '1';
- } else if (alphaPower === 1) {
- result += 'a';
- } else {
- result += 'a^';
- result += alphaPower;
- }
- }
- if (degree !== 0) {
- if (degree === 1) {
- result += 'x';
- } else {
- result += 'x^';
- result += degree;
- }
- }
- }
+ if (degree !== 0) {
+ if (degree === 1) {
+ result += 'x';
+ } else {
+ result += 'x^';
+ result += degree;
+ }
}
- return result;
+ }
}
+ return result;
+ }
}
diff --git a/src/core/common/reedsolomon/GenericGF.ts b/src/core/common/reedsolomon/GenericGF.ts
index af7318e3..b9bcb45a 100644
--- a/src/core/common/reedsolomon/GenericGF.ts
+++ b/src/core/common/reedsolomon/GenericGF.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common.reedsolomon {*/
+/* namespace com.google.zxing.common.reedsolomon { */
import GenericGFPoly from './GenericGFPoly';
import AbstractGenericGF from './AbstractGenericGF';
@@ -57,11 +57,11 @@ export default class GenericGF extends AbstractGenericGF {
* @param b the factor b in the generator polynomial can be 0- or 1-based
* (g(x) = (x+a^b)(x+a^(b+1))...(x+a^(b+2t-1))).
* In most cases it should be 1, but for QR code it is 0.
- */
+ */
public constructor(
- private primitive: number /*int*/,
- private size: number /*int*/,
- private generatorBase: number /*int*/
+ private primitive: number /* int */,
+ private size: number /* int */,
+ private generatorBase: number /* int */
) {
super();
const expTable = new Int32Array(size);
@@ -97,10 +97,10 @@ export default class GenericGF extends AbstractGenericGF {
/**
* @return the monomial representing coefficient * x^degree
- */
+ */
public buildMonomial(
- degree: number /*int*/,
- coefficient: number /*int*/
+ degree: number /* int */,
+ coefficient: number /* int */
): GenericGFPoly {
if (degree < 0) {
throw new IllegalArgumentException();
@@ -115,8 +115,8 @@ export default class GenericGF extends AbstractGenericGF {
/**
* @return multiplicative inverse of a
- */
- public inverse(a: number /*int*/): number /*int*/ {
+ */
+ public inverse(a: number /* int */): number /* int */ {
if (a === 0) {
throw new ArithmeticException();
}
@@ -125,8 +125,8 @@ export default class GenericGF extends AbstractGenericGF {
/**
* @return product of a and b in GF(size)
- */
- public multiply(a: number /*int*/, b: number /*int*/): number /*int*/ {
+ */
+ public multiply(a: number /* int */, b: number /* int */): number /* int */ {
if (a === 0 || b === 0) {
return 0;
}
@@ -135,15 +135,15 @@ export default class GenericGF extends AbstractGenericGF {
];
}
- public getSize(): number /*int*/ {
+ public getSize(): number /* int */ {
return this.size;
}
- public getGeneratorBase(): number /*int*/ {
+ public getGeneratorBase(): number /* int */ {
return this.generatorBase;
}
- /*@Override*/
+ /* @Override */
public toString(): string {
return (
'GF(0x' + Integer.toHexString(this.primitive) + ',' + this.size + ')'
diff --git a/src/core/common/reedsolomon/GenericGFPoly.ts b/src/core/common/reedsolomon/GenericGFPoly.ts
index 9de5e245..e79cf492 100644
--- a/src/core/common/reedsolomon/GenericGFPoly.ts
+++ b/src/core/common/reedsolomon/GenericGFPoly.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common.reedsolomon {*/
+/* namespace com.google.zxing.common.reedsolomon { */
import AbstractGenericGF from './AbstractGenericGF';
@@ -32,249 +32,249 @@ import IllegalArgumentException from '../../IllegalArgumentException';
*/
export default class GenericGFPoly {
- private field: AbstractGenericGF;
- private coefficients: Int32Array;
+ private field: AbstractGenericGF;
+ private coefficients: Int32Array;
- /**
- * @param field the {@link GenericGF} instance representing the field to use
- * to perform computations
- * @param coefficients coefficients as ints representing elements of GF(size), arranged
- * from most significant (highest-power term) coefficient to least significant
- * @throws IllegalArgumentException if argument is null or empty,
- * or if leading coefficient is 0 and this is not a
- * constant polynomial (that is, it is not the monomial "0")
- */
- public constructor(field: AbstractGenericGF, coefficients: Int32Array) {
- if (coefficients.length === 0) {
- throw new IllegalArgumentException();
- }
- this.field = field;
- const coefficientsLength = coefficients.length;
- if (coefficientsLength > 1 && coefficients[0] === 0) {
- // Leading term must be non-zero for anything except the constant polynomial "0"
- let firstNonZero = 1;
- while (firstNonZero < coefficientsLength && coefficients[firstNonZero] === 0) {
- firstNonZero++;
- }
- if (firstNonZero === coefficientsLength) {
- this.coefficients = Int32Array.from([0]);
- } else {
- this.coefficients = new Int32Array(coefficientsLength - firstNonZero);
- System.arraycopy(coefficients,
- firstNonZero,
- this.coefficients,
- 0,
- this.coefficients.length);
- }
- } else {
- this.coefficients = coefficients;
- }
+ /**
+ * @param field the {@link GenericGF} instance representing the field to use
+ * to perform computations
+ * @param coefficients coefficients as ints representing elements of GF(size), arranged
+ * from most significant (highest-power term) coefficient to least significant
+ * @throws IllegalArgumentException if argument is null or empty,
+ * or if leading coefficient is 0 and this is not a
+ * constant polynomial (that is, it is not the monomial "0")
+ */
+ public constructor(field: AbstractGenericGF, coefficients: Int32Array) {
+ if (coefficients.length === 0) {
+ throw new IllegalArgumentException();
}
-
- public getCoefficients(): Int32Array {
- return this.coefficients;
+ this.field = field;
+ const coefficientsLength = coefficients.length;
+ if (coefficientsLength > 1 && coefficients[0] === 0) {
+ // Leading term must be non-zero for anything except the constant polynomial "0"
+ let firstNonZero = 1;
+ while (firstNonZero < coefficientsLength && coefficients[firstNonZero] === 0) {
+ firstNonZero++;
+ }
+ if (firstNonZero === coefficientsLength) {
+ this.coefficients = Int32Array.from([0]);
+ } else {
+ this.coefficients = new Int32Array(coefficientsLength - firstNonZero);
+ System.arraycopy(coefficients,
+ firstNonZero,
+ this.coefficients,
+ 0,
+ this.coefficients.length);
+ }
+ } else {
+ this.coefficients = coefficients;
}
+ }
- /**
- * @return degree of this polynomial
- */
- public getDegree(): number {
- return this.coefficients.length - 1;
- }
+ public getCoefficients(): Int32Array {
+ return this.coefficients;
+ }
- /**
- * @return true iff this polynomial is the monomial "0"
- */
- public isZero(): boolean {
- return this.coefficients[0] === 0;
- }
+ /**
+ * @return degree of this polynomial
+ */
+ public getDegree(): number {
+ return this.coefficients.length - 1;
+ }
+
+ /**
+ * @return true iff this polynomial is the monomial "0"
+ */
+ public isZero(): boolean {
+ return this.coefficients[0] === 0;
+ }
- /**
- * @return coefficient of x^degree term in this polynomial
- */
- public getCoefficient(degree: number /*int*/): number {
- return this.coefficients[this.coefficients.length - 1 - degree];
+ /**
+ * @return coefficient of x^degree term in this polynomial
+ */
+ public getCoefficient(degree: number /* int */): number {
+ return this.coefficients[this.coefficients.length - 1 - degree];
+ }
+
+ /**
+ * @return evaluation of this polynomial at a given point
+ */
+ public evaluateAt(a: number /* int */): number {
+ if (a === 0) {
+ // Just return the x^0 coefficient
+ return this.getCoefficient(0);
}
+ const coefficients = this.coefficients;
+ let result: number;
+ if (a === 1) {
+ // Just the sum of the coefficients
+ result = 0;
+ for (let i = 0, length = coefficients.length; i !== length; i++) {
+ const coefficient = coefficients[i];
+ result = AbstractGenericGF.addOrSubtract(result, coefficient);
+ }
+ return result;
+ }
+ result = coefficients[0];
+ const size = coefficients.length;
+ const field = this.field;
+ for (let i = 1; i < size; i++) {
+ result = AbstractGenericGF.addOrSubtract(field.multiply(a, result), coefficients[i]);
+ }
+ return result;
+ }
- /**
- * @return evaluation of this polynomial at a given point
- */
- public evaluateAt(a: number /*int*/): number {
- if (a === 0) {
- // Just return the x^0 coefficient
- return this.getCoefficient(0);
- }
- const coefficients = this.coefficients;
- let result: number;
- if (a === 1) {
- // Just the sum of the coefficients
- result = 0;
- for (let i = 0, length = coefficients.length; i !== length; i++) {
- const coefficient = coefficients[i];
- result = AbstractGenericGF.addOrSubtract(result, coefficient);
- }
- return result;
- }
- result = coefficients[0];
- const size = coefficients.length;
- const field = this.field;
- for (let i = 1; i < size; i++) {
- result = AbstractGenericGF.addOrSubtract(field.multiply(a, result), coefficients[i]);
- }
- return result;
+ public addOrSubtract(other: GenericGFPoly): GenericGFPoly {
+ if (!this.field.equals(other.field)) {
+ throw new IllegalArgumentException('GenericGFPolys do not have same GenericGF field');
+ }
+ if (this.isZero()) {
+ return other;
+ }
+ if (other.isZero()) {
+ return this;
}
- public addOrSubtract(other: GenericGFPoly): GenericGFPoly {
- if (!this.field.equals(other.field)) {
- throw new IllegalArgumentException('GenericGFPolys do not have same GenericGF field');
- }
- if (this.isZero()) {
- return other;
- }
- if (other.isZero()) {
- return this;
- }
+ let smallerCoefficients = this.coefficients;
+ let largerCoefficients = other.coefficients;
+ if (smallerCoefficients.length > largerCoefficients.length) {
+ const temp = smallerCoefficients;
+ smallerCoefficients = largerCoefficients;
+ largerCoefficients = temp;
+ }
+ let sumDiff = new Int32Array(largerCoefficients.length);
+ const lengthDiff = largerCoefficients.length - smallerCoefficients.length;
+ // Copy high-order terms only found in higher-degree polynomial's coefficients
+ System.arraycopy(largerCoefficients, 0, sumDiff, 0, lengthDiff);
- let smallerCoefficients = this.coefficients;
- let largerCoefficients = other.coefficients;
- if (smallerCoefficients.length > largerCoefficients.length) {
- const temp = smallerCoefficients;
- smallerCoefficients = largerCoefficients;
- largerCoefficients = temp;
- }
- let sumDiff = new Int32Array(largerCoefficients.length);
- const lengthDiff = largerCoefficients.length - smallerCoefficients.length;
- // Copy high-order terms only found in higher-degree polynomial's coefficients
- System.arraycopy(largerCoefficients, 0, sumDiff, 0, lengthDiff);
+ for (let i = lengthDiff; i < largerCoefficients.length; i++) {
+ sumDiff[i] = AbstractGenericGF.addOrSubtract(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);
+ }
- for (let i = lengthDiff; i < largerCoefficients.length; i++) {
- sumDiff[i] = AbstractGenericGF.addOrSubtract(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);
- }
+ return new GenericGFPoly(this.field, sumDiff);
+ }
- return new GenericGFPoly(this.field, sumDiff);
+ public multiply(other: GenericGFPoly): GenericGFPoly {
+ if (!this.field.equals(other.field)) {
+ throw new IllegalArgumentException('GenericGFPolys do not have same GenericGF field');
}
-
- public multiply(other: GenericGFPoly): GenericGFPoly {
- if (!this.field.equals(other.field)) {
- throw new IllegalArgumentException('GenericGFPolys do not have same GenericGF field');
- }
- if (this.isZero() || other.isZero()) {
- return this.field.getZero();
- }
- const aCoefficients = this.coefficients;
- const aLength = aCoefficients.length;
- const bCoefficients = other.coefficients;
- const bLength = bCoefficients.length;
- const product = new Int32Array(aLength + bLength - 1);
- const field = this.field;
- for (let i = 0; i < aLength; i++) {
- const aCoeff = aCoefficients[i];
- for (let j = 0; j < bLength; j++) {
- product[i + j] = AbstractGenericGF.addOrSubtract(product[i + j],
- field.multiply(aCoeff, bCoefficients[j]));
- }
- }
- return new GenericGFPoly(field, product);
+ if (this.isZero() || other.isZero()) {
+ return this.field.getZero();
}
-
- public multiplyScalar(scalar: number /*int*/): GenericGFPoly {
- if (scalar === 0) {
- return this.field.getZero();
- }
- if (scalar === 1) {
- return this;
- }
- const size = this.coefficients.length;
- const field = this.field;
- const product = new Int32Array(size);
- const coefficients = this.coefficients;
- for (let i = 0; i < size; i++) {
- product[i] = field.multiply(coefficients[i], scalar);
- }
- return new GenericGFPoly(field, product);
+ const aCoefficients = this.coefficients;
+ const aLength = aCoefficients.length;
+ const bCoefficients = other.coefficients;
+ const bLength = bCoefficients.length;
+ const product = new Int32Array(aLength + bLength - 1);
+ const field = this.field;
+ for (let i = 0; i < aLength; i++) {
+ const aCoeff = aCoefficients[i];
+ for (let j = 0; j < bLength; j++) {
+ product[i + j] = AbstractGenericGF.addOrSubtract(product[i + j],
+ field.multiply(aCoeff, bCoefficients[j]));
+ }
}
+ return new GenericGFPoly(field, product);
+ }
- public multiplyByMonomial(degree: number /*int*/, coefficient: number /*int*/): GenericGFPoly {
- if (degree < 0) {
- throw new IllegalArgumentException();
- }
- if (coefficient === 0) {
- return this.field.getZero();
- }
- const coefficients = this.coefficients;
- const size = coefficients.length;
- const product = new Int32Array(size + degree);
- const field = this.field;
- for (let i = 0; i < size; i++) {
- product[i] = field.multiply(coefficients[i], coefficient);
- }
- return new GenericGFPoly(field, product);
+ public multiplyScalar(scalar: number /* int */): GenericGFPoly {
+ if (scalar === 0) {
+ return this.field.getZero();
+ }
+ if (scalar === 1) {
+ return this;
}
+ const size = this.coefficients.length;
+ const field = this.field;
+ const product = new Int32Array(size);
+ const coefficients = this.coefficients;
+ for (let i = 0; i < size; i++) {
+ product[i] = field.multiply(coefficients[i], scalar);
+ }
+ return new GenericGFPoly(field, product);
+ }
- public divide(other: GenericGFPoly): GenericGFPoly[] {
- if (!this.field.equals(other.field)) {
- throw new IllegalArgumentException('GenericGFPolys do not have same GenericGF field');
- }
- if (other.isZero()) {
- throw new IllegalArgumentException('Divide by 0');
- }
+ public multiplyByMonomial(degree: number /* int */, coefficient: number /* int */): GenericGFPoly {
+ if (degree < 0) {
+ throw new IllegalArgumentException();
+ }
+ if (coefficient === 0) {
+ return this.field.getZero();
+ }
+ const coefficients = this.coefficients;
+ const size = coefficients.length;
+ const product = new Int32Array(size + degree);
+ const field = this.field;
+ for (let i = 0; i < size; i++) {
+ product[i] = field.multiply(coefficients[i], coefficient);
+ }
+ return new GenericGFPoly(field, product);
+ }
- const field = this.field;
+ public divide(other: GenericGFPoly): GenericGFPoly[] {
+ if (!this.field.equals(other.field)) {
+ throw new IllegalArgumentException('GenericGFPolys do not have same GenericGF field');
+ }
+ if (other.isZero()) {
+ throw new IllegalArgumentException('Divide by 0');
+ }
- let quotient: GenericGFPoly = field.getZero();
- let remainder: GenericGFPoly = this;
+ const field = this.field;
- const denominatorLeadingTerm = other.getCoefficient(other.getDegree());
- const inverseDenominatorLeadingTerm = field.inverse(denominatorLeadingTerm);
+ let quotient: GenericGFPoly = field.getZero();
+ let remainder: GenericGFPoly = this;
- while (remainder.getDegree() >= other.getDegree() && !remainder.isZero()) {
- const degreeDifference = remainder.getDegree() - other.getDegree();
- const scale = field.multiply(remainder.getCoefficient(remainder.getDegree()), inverseDenominatorLeadingTerm);
- const term = other.multiplyByMonomial(degreeDifference, scale);
- const iterationQuotient = field.buildMonomial(degreeDifference, scale);
- quotient = quotient.addOrSubtract(iterationQuotient);
- remainder = remainder.addOrSubtract(term);
- }
+ const denominatorLeadingTerm = other.getCoefficient(other.getDegree());
+ const inverseDenominatorLeadingTerm = field.inverse(denominatorLeadingTerm);
- return [quotient, remainder];
+ while (remainder.getDegree() >= other.getDegree() && !remainder.isZero()) {
+ const degreeDifference = remainder.getDegree() - other.getDegree();
+ const scale = field.multiply(remainder.getCoefficient(remainder.getDegree()), inverseDenominatorLeadingTerm);
+ const term = other.multiplyByMonomial(degreeDifference, scale);
+ const iterationQuotient = field.buildMonomial(degreeDifference, scale);
+ quotient = quotient.addOrSubtract(iterationQuotient);
+ remainder = remainder.addOrSubtract(term);
}
- /*@Override*/
- public toString(): string {
- let result = '';
- for (let degree = this.getDegree(); degree >= 0; degree--) {
- let coefficient = this.getCoefficient(degree);
- if (coefficient !== 0) {
- if (coefficient < 0) {
- result += ' - ';
- coefficient = -coefficient;
- } else {
- if (result.length > 0) {
- result += ' + ';
- }
- }
- if (degree === 0 || coefficient !== 1) {
- const alphaPower = this.field.log(coefficient);
- if (alphaPower === 0) {
- result += '1';
- } else if (alphaPower === 1) {
- result += 'a';
- } else {
- result += 'a^';
- result += alphaPower;
- }
- }
- if (degree !== 0) {
- if (degree === 1) {
- result += 'x';
- } else {
- result += 'x^';
- result += degree;
- }
- }
- }
+ return [quotient, remainder];
+ }
+
+ /* @Override */
+ public toString(): string {
+ let result = '';
+ for (let degree = this.getDegree(); degree >= 0; degree--) {
+ let coefficient = this.getCoefficient(degree);
+ if (coefficient !== 0) {
+ if (coefficient < 0) {
+ result += ' - ';
+ coefficient = -coefficient;
+ } else {
+ if (result.length > 0) {
+ result += ' + ';
+ }
+ }
+ if (degree === 0 || coefficient !== 1) {
+ const alphaPower = this.field.log(coefficient);
+ if (alphaPower === 0) {
+ result += '1';
+ } else if (alphaPower === 1) {
+ result += 'a';
+ } else {
+ result += 'a^';
+ result += alphaPower;
+ }
+ }
+ if (degree !== 0) {
+ if (degree === 1) {
+ result += 'x';
+ } else {
+ result += 'x^';
+ result += degree;
+ }
}
- return result;
+ }
}
+ return result;
+ }
}
diff --git a/src/core/common/reedsolomon/ReedSolomonDecoder.ts b/src/core/common/reedsolomon/ReedSolomonDecoder.ts
index 1f2a5de8..1a2fb218 100644
--- a/src/core/common/reedsolomon/ReedSolomonDecoder.ts
+++ b/src/core/common/reedsolomon/ReedSolomonDecoder.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common.reedsolomon {*/
+/* namespace com.google.zxing.common.reedsolomon { */
import GenericGF from './GenericGF';
import GenericGFPoly from './GenericGFPoly';
@@ -46,150 +46,150 @@ import IllegalStateException from '../../IllegalStateException';
*/
export default class ReedSolomonDecoder {
- public constructor(private field: GenericGF) { }
-
- /**
- * Decodes given set of received codewords, which include both data and error-correction
- * codewords. Really, this means it uses Reed-Solomon to detect and correct errors, in-place,
- * in the input.
- *
- * @param received data and error-correction codewords
- * @param twoS number of error-correction codewords available
- * @throws ReedSolomonException if decoding fails for any reason
- */
- public decode(received: Int32Array, twoS: number /*int*/): void /*throws ReedSolomonException*/ {
- const field = this.field;
- const poly = new GenericGFPoly(field, received);
- const syndromeCoefficients = new Int32Array(twoS);
- let noError: boolean = true;
- for (let i = 0; i < twoS; i++) {
- const evalResult = poly.evaluateAt(field.exp(i + field.getGeneratorBase()));
- syndromeCoefficients[syndromeCoefficients.length - 1 - i] = evalResult;
- if (evalResult !== 0) {
- noError = false;
- }
- }
- if (noError) {
- return;
- }
- const syndrome = new GenericGFPoly(field, syndromeCoefficients);
- const sigmaOmega = this.runEuclideanAlgorithm(field.buildMonomial(twoS, 1), syndrome, twoS);
- const sigma = sigmaOmega[0];
- const omega = sigmaOmega[1];
- const errorLocations = this.findErrorLocations(sigma);
- const errorMagnitudes = this.findErrorMagnitudes(omega, errorLocations);
- for (let i = 0; i < errorLocations.length; i++) {
- const position = received.length - 1 - field.log(errorLocations[i]);
- if (position < 0) {
- throw new ReedSolomonException('Bad error location');
- }
- received[position] = GenericGF.addOrSubtract(received[position], errorMagnitudes[i]);
- }
- }
-
- private runEuclideanAlgorithm(a: GenericGFPoly, b: GenericGFPoly, R: number /*int*/): GenericGFPoly[] {
- // Assume a's degree is >= b's
- if (a.getDegree() < b.getDegree()) {
- const temp = a;
- a = b;
- b = temp;
- }
-
- const field = this.field;
-
- let rLast = a;
- let r = b;
- let tLast = field.getZero();
- let t = field.getOne();
-
- // Run Euclidean algorithm until r's degree is less than R/2
- while (r.getDegree() >= (R / 2 | 0)) {
- let rLastLast = rLast;
- let tLastLast = tLast;
- rLast = r;
- tLast = t;
-
- // Divide rLastLast by rLast, with quotient in q and remainder in r
- if (rLast.isZero()) {
- // Oops, Euclidean algorithm already terminated?
- throw new ReedSolomonException('r_{i-1} was zero');
- }
- r = rLastLast;
- let q = field.getZero();
- const denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree());
- const dltInverse = field.inverse(denominatorLeadingTerm);
- while (r.getDegree() >= rLast.getDegree() && !r.isZero()) {
- const degreeDiff = r.getDegree() - rLast.getDegree();
- const scale = field.multiply(r.getCoefficient(r.getDegree()), dltInverse);
- q = q.addOrSubtract(field.buildMonomial(degreeDiff, scale));
- r = r.addOrSubtract(rLast.multiplyByMonomial(degreeDiff, scale));
- }
-
- t = q.multiply(tLast).addOrSubtract(tLastLast);
-
- if (r.getDegree() >= rLast.getDegree()) {
- throw new IllegalStateException('Division algorithm failed to reduce polynomial?');
- }
- }
+ public constructor(private field: GenericGF) { }
- const sigmaTildeAtZero = t.getCoefficient(0);
- if (sigmaTildeAtZero === 0) {
- throw new ReedSolomonException('sigmaTilde(0) was zero');
- }
+ /**
+ * Decodes given set of received codewords, which include both data and error-correction
+ * codewords. Really, this means it uses Reed-Solomon to detect and correct errors, in-place,
+ * in the input.
+ *
+ * @param received data and error-correction codewords
+ * @param twoS number of error-correction codewords available
+ * @throws ReedSolomonException if decoding fails for any reason
+ */
+ public decode(received: Int32Array, twoS: number /* int */): void /* throws ReedSolomonException */ {
+ const field = this.field;
+ const poly = new GenericGFPoly(field, received);
+ const syndromeCoefficients = new Int32Array(twoS);
+ let noError: boolean = true;
+ for (let i = 0; i < twoS; i++) {
+ const evalResult = poly.evaluateAt(field.exp(i + field.getGeneratorBase()));
+ syndromeCoefficients[syndromeCoefficients.length - 1 - i] = evalResult;
+ if (evalResult !== 0) {
+ noError = false;
+ }
+ }
+ if (noError) {
+ return;
+ }
+ const syndrome = new GenericGFPoly(field, syndromeCoefficients);
+ const sigmaOmega = this.runEuclideanAlgorithm(field.buildMonomial(twoS, 1), syndrome, twoS);
+ const sigma = sigmaOmega[0];
+ const omega = sigmaOmega[1];
+ const errorLocations = this.findErrorLocations(sigma);
+ const errorMagnitudes = this.findErrorMagnitudes(omega, errorLocations);
+ for (let i = 0; i < errorLocations.length; i++) {
+ const position = received.length - 1 - field.log(errorLocations[i]);
+ if (position < 0) {
+ throw new ReedSolomonException('Bad error location');
+ }
+ received[position] = GenericGF.addOrSubtract(received[position], errorMagnitudes[i]);
+ }
+ }
+
+ private runEuclideanAlgorithm(a: GenericGFPoly, b: GenericGFPoly, R: number /* int */): GenericGFPoly[] {
+ // Assume a's degree is >= b's
+ if (a.getDegree() < b.getDegree()) {
+ const temp = a;
+ a = b;
+ b = temp;
+ }
- const inverse = field.inverse(sigmaTildeAtZero);
- const sigma = t.multiplyScalar(inverse);
- const omega = r.multiplyScalar(inverse);
- return [sigma, omega];
+ const field = this.field;
+
+ let rLast = a;
+ let r = b;
+ let tLast = field.getZero();
+ let t = field.getOne();
+
+ // Run Euclidean algorithm until r's degree is less than R/2
+ while (r.getDegree() >= (R / 2 | 0)) {
+ let rLastLast = rLast;
+ let tLastLast = tLast;
+ rLast = r;
+ tLast = t;
+
+ // Divide rLastLast by rLast, with quotient in q and remainder in r
+ if (rLast.isZero()) {
+ // Oops, Euclidean algorithm already terminated?
+ throw new ReedSolomonException('r_{i-1} was zero');
+ }
+ r = rLastLast;
+ let q = field.getZero();
+ const denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree());
+ const dltInverse = field.inverse(denominatorLeadingTerm);
+ while (r.getDegree() >= rLast.getDegree() && !r.isZero()) {
+ const degreeDiff = r.getDegree() - rLast.getDegree();
+ const scale = field.multiply(r.getCoefficient(r.getDegree()), dltInverse);
+ q = q.addOrSubtract(field.buildMonomial(degreeDiff, scale));
+ r = r.addOrSubtract(rLast.multiplyByMonomial(degreeDiff, scale));
+ }
+
+ t = q.multiply(tLast).addOrSubtract(tLastLast);
+
+ if (r.getDegree() >= rLast.getDegree()) {
+ throw new IllegalStateException('Division algorithm failed to reduce polynomial?');
+ }
}
- private findErrorLocations(errorLocator: GenericGFPoly): Int32Array /*throws ReedSolomonException*/ {
- // This is a direct application of Chien's search
- const numErrors = errorLocator.getDegree();
- if (numErrors === 1) { // shortcut
- return Int32Array.from([errorLocator.getCoefficient(1)]);
- }
- const result = new Int32Array(numErrors);
- let e = 0;
- const field = this.field;
- for (let i = 1; i < field.getSize() && e < numErrors; i++) {
- if (errorLocator.evaluateAt(i) === 0) {
- result[e] = field.inverse(i);
- e++;
- }
- }
- if (e !== numErrors) {
- throw new ReedSolomonException('Error locator degree does not match number of roots');
- }
- return result;
+ const sigmaTildeAtZero = t.getCoefficient(0);
+ if (sigmaTildeAtZero === 0) {
+ throw new ReedSolomonException('sigmaTilde(0) was zero');
}
- private findErrorMagnitudes(errorEvaluator: GenericGFPoly, errorLocations: Int32Array): Int32Array {
- // This is directly applying Forney's Formula
- const s = errorLocations.length;
- const result = new Int32Array(s);
- const field = this.field;
- for (let i = 0; i < s; i++) {
- const xiInverse = field.inverse(errorLocations[i]);
- let denominator = 1;
- for (let j = 0; j < s; j++) {
- if (i !== j) {
- // denominator = field.multiply(denominator,
- // GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse)))
- // Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug.
- // Below is a funny-looking workaround from Steven Parkes
- const term = field.multiply(errorLocations[j], xiInverse);
- const termPlus1 = (term & 0x1) === 0 ? term | 1 : term & ~1;
- denominator = field.multiply(denominator, termPlus1);
- }
- }
- result[i] = field.multiply(errorEvaluator.evaluateAt(xiInverse),
- field.inverse(denominator));
- if (field.getGeneratorBase() !== 0) {
- result[i] = field.multiply(result[i], xiInverse);
- }
+ const inverse = field.inverse(sigmaTildeAtZero);
+ const sigma = t.multiplyScalar(inverse);
+ const omega = r.multiplyScalar(inverse);
+ return [sigma, omega];
+ }
+
+ private findErrorLocations(errorLocator: GenericGFPoly): Int32Array /* throws ReedSolomonException */ {
+ // This is a direct application of Chien's search
+ const numErrors = errorLocator.getDegree();
+ if (numErrors === 1) { // shortcut
+ return Int32Array.from([errorLocator.getCoefficient(1)]);
+ }
+ const result = new Int32Array(numErrors);
+ let e = 0;
+ const field = this.field;
+ for (let i = 1; i < field.getSize() && e < numErrors; i++) {
+ if (errorLocator.evaluateAt(i) === 0) {
+ result[e] = field.inverse(i);
+ e++;
+ }
+ }
+ if (e !== numErrors) {
+ throw new ReedSolomonException('Error locator degree does not match number of roots');
+ }
+ return result;
+ }
+
+ private findErrorMagnitudes(errorEvaluator: GenericGFPoly, errorLocations: Int32Array): Int32Array {
+ // This is directly applying Forney's Formula
+ const s = errorLocations.length;
+ const result = new Int32Array(s);
+ const field = this.field;
+ for (let i = 0; i < s; i++) {
+ const xiInverse = field.inverse(errorLocations[i]);
+ let denominator = 1;
+ for (let j = 0; j < s; j++) {
+ if (i !== j) {
+ // denominator = field.multiply(denominator,
+ // GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse)))
+ // Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug.
+ // Below is a funny-looking workaround from Steven Parkes
+ const term = field.multiply(errorLocations[j], xiInverse);
+ const termPlus1 = (term & 0x1) === 0 ? term | 1 : term & ~1;
+ denominator = field.multiply(denominator, termPlus1);
}
- return result;
+ }
+ result[i] = field.multiply(errorEvaluator.evaluateAt(xiInverse),
+ field.inverse(denominator));
+ if (field.getGeneratorBase() !== 0) {
+ result[i] = field.multiply(result[i], xiInverse);
+ }
}
+ return result;
+ }
}
diff --git a/src/core/common/reedsolomon/ReedSolomonEncoder.ts b/src/core/common/reedsolomon/ReedSolomonEncoder.ts
index a97eec14..52e3db89 100644
--- a/src/core/common/reedsolomon/ReedSolomonEncoder.ts
+++ b/src/core/common/reedsolomon/ReedSolomonEncoder.ts
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.common.reedsolomon {*/
+/* namespace com.google.zxing.common.reedsolomon { */
-/*import java.util.ArrayList;*/
-/*import java.util.List;*/
+/* import java.util.ArrayList; */
+/* import java.util.List; */
import GenericGF from './GenericGF';
import GenericGFPoly from './GenericGFPoly';
@@ -33,77 +33,77 @@ import IllegalArgumentException from '../../IllegalArgumentException';
*/
export default class ReedSolomonEncoder {
- private field: GenericGF;
- private cachedGenerators: GenericGFPoly[];
+ private field: GenericGF;
+ private cachedGenerators: GenericGFPoly[];
- /**
- * A reed solomon error-correcting encoding constructor is created by
- * passing as Galois Field with of size equal to the number of code
- * words (symbols) in the alphabet (the number of values in each
- * element of arrays that are encoded/decoded).
- * @param field A galois field with a number of elements equal to the size
- * of the alphabet of symbols to encode.
- */
- public constructor(field: GenericGF) {
- this.field = field;
- this.cachedGenerators = [];
- this.cachedGenerators.push(new GenericGFPoly(field, Int32Array.from([1])));
- }
+ /**
+ * A reed solomon error-correcting encoding constructor is created by
+ * passing as Galois Field with of size equal to the number of code
+ * words (symbols) in the alphabet (the number of values in each
+ * element of arrays that are encoded/decoded).
+ * @param field A galois field with a number of elements equal to the size
+ * of the alphabet of symbols to encode.
+ */
+ public constructor(field: GenericGF) {
+ this.field = field;
+ this.cachedGenerators = [];
+ this.cachedGenerators.push(new GenericGFPoly(field, Int32Array.from([1])));
+ }
- private buildGenerator(degree: number /*int*/): GenericGFPoly {
- const cachedGenerators = this.cachedGenerators;
- if (degree >= cachedGenerators.length) {
- let lastGenerator = cachedGenerators[cachedGenerators.length - 1];
- const field = this.field;
- for (let d = cachedGenerators.length; d <= degree; d++) {
- const nextGenerator = lastGenerator.multiply(
- new GenericGFPoly(field, Int32Array.from([1, field.exp(d - 1 + field.getGeneratorBase())])));
- cachedGenerators.push(nextGenerator);
- lastGenerator = nextGenerator;
- }
- }
- return cachedGenerators[degree];
+ private buildGenerator(degree: number /* int */): GenericGFPoly {
+ const cachedGenerators = this.cachedGenerators;
+ if (degree >= cachedGenerators.length) {
+ let lastGenerator = cachedGenerators[cachedGenerators.length - 1];
+ const field = this.field;
+ for (let d = cachedGenerators.length; d <= degree; d++) {
+ const nextGenerator = lastGenerator.multiply(
+ new GenericGFPoly(field, Int32Array.from([1, field.exp(d - 1 + field.getGeneratorBase())])));
+ cachedGenerators.push(nextGenerator);
+ lastGenerator = nextGenerator;
+ }
}
+ return cachedGenerators[degree];
+ }
- /**
- * Encode a sequence of code words (symbols) using Reed-Solomon to allow decoders
- * to detect and correct errors that may have been introduced when the resulting
- * data is stored or transmitted.
- *
- * @param toEncode array used for both and output. Caller initializes the array with
- * the code words (symbols) to be encoded followed by empty elements allocated to make
- * space for error-correction code words in the encoded output. The array contains
- * the encdoded output when encode returns. Code words are encoded as numbers from
- * 0 to n-1, where n is the number of possible code words (symbols), as determined
- * by the size of the Galois Field passed in the constructor of this object.
- * @param ecBytes the number of elements reserved in the array (first parameter)
- * to store error-correction code words. Thus, the number of code words (symbols)
- * to encode in the first parameter is thus toEncode.length - ecBytes.
- * Note, the use of "bytes" in the name of this parameter is misleading, as there may
- * be more or fewer than 256 symbols being encoded, as determined by the number of
- * elements in the Galois Field passed as a constructor to this object.
- * @throws IllegalArgumentException thrown in response to validation errros.
- */
- public encode(toEncode: Int32Array, ecBytes: number /*int*/): void {
- if (ecBytes === 0) {
- throw new IllegalArgumentException('No error correction bytes');
- }
- const dataBytes = toEncode.length - ecBytes;
- if (dataBytes <= 0) {
- throw new IllegalArgumentException('No data bytes provided');
- }
- const generator = this.buildGenerator(ecBytes);
- const infoCoefficients: Int32Array = new Int32Array(dataBytes);
- System.arraycopy(toEncode, 0, infoCoefficients, 0, dataBytes);
- let info = new GenericGFPoly(this.field, infoCoefficients);
- info = info.multiplyByMonomial(ecBytes, 1);
- const remainder = info.divide(generator)[1];
- const coefficients = remainder.getCoefficients();
- const numZeroCoefficients = ecBytes - coefficients.length;
- for (let i = 0; i < numZeroCoefficients; i++) {
- toEncode[dataBytes + i] = 0;
- }
- System.arraycopy(coefficients, 0, toEncode, dataBytes + numZeroCoefficients, coefficients.length);
+ /**
+ * Encode a sequence of code words (symbols) using Reed-Solomon to allow decoders
+ * to detect and correct errors that may have been introduced when the resulting
+ * data is stored or transmitted.
+ *
+ * @param toEncode array used for both and output. Caller initializes the array with
+ * the code words (symbols) to be encoded followed by empty elements allocated to make
+ * space for error-correction code words in the encoded output. The array contains
+ * the encdoded output when encode returns. Code words are encoded as numbers from
+ * 0 to n-1, where n is the number of possible code words (symbols), as determined
+ * by the size of the Galois Field passed in the constructor of this object.
+ * @param ecBytes the number of elements reserved in the array (first parameter)
+ * to store error-correction code words. Thus, the number of code words (symbols)
+ * to encode in the first parameter is thus toEncode.length - ecBytes.
+ * Note, the use of "bytes" in the name of this parameter is misleading, as there may
+ * be more or fewer than 256 symbols being encoded, as determined by the number of
+ * elements in the Galois Field passed as a constructor to this object.
+ * @throws IllegalArgumentException thrown in response to validation errros.
+ */
+ public encode(toEncode: Int32Array, ecBytes: number /* int */): void {
+ if (ecBytes === 0) {
+ throw new IllegalArgumentException('No error correction bytes');
+ }
+ const dataBytes = toEncode.length - ecBytes;
+ if (dataBytes <= 0) {
+ throw new IllegalArgumentException('No data bytes provided');
+ }
+ const generator = this.buildGenerator(ecBytes);
+ const infoCoefficients: Int32Array = new Int32Array(dataBytes);
+ System.arraycopy(toEncode, 0, infoCoefficients, 0, dataBytes);
+ let info = new GenericGFPoly(this.field, infoCoefficients);
+ info = info.multiplyByMonomial(ecBytes, 1);
+ const remainder = info.divide(generator)[1];
+ const coefficients = remainder.getCoefficients();
+ const numZeroCoefficients = ecBytes - coefficients.length;
+ for (let i = 0; i < numZeroCoefficients; i++) {
+ toEncode[dataBytes + i] = 0;
}
+ System.arraycopy(coefficients, 0, toEncode, dataBytes + numZeroCoefficients, coefficients.length);
+ }
}
diff --git a/src/core/datamatrix/DataMatrixReader.ts b/src/core/datamatrix/DataMatrixReader.ts
index 90d45997..9f1c5ef7 100644
--- a/src/core/datamatrix/DataMatrixReader.ts
+++ b/src/core/datamatrix/DataMatrixReader.ts
@@ -47,7 +47,7 @@ export default class DataMatrixReader implements Reader {
* @throws NotFoundException if a Data Matrix code cannot be found
* @throws FormatException if a Data Matrix code cannot be decoded
* @throws ChecksumException if error correction fails
- */
+ */
// @Override
// public Result decode(BinaryBitmap image) throws NotFoundException, ChecksumException, FormatException {
// return decode(image, null);
@@ -100,7 +100,7 @@ export default class DataMatrixReader implements Reader {
* case.
*
* @see com.google.zxing.qrcode.QRCodeReader#extractPureBits(BitMatrix)
- */
+ */
private static extractPureBits(image: BitMatrix): BitMatrix {
const leftTopBlack = image.getTopLeftOnBit();
diff --git a/src/core/datamatrix/decoder/BitMatrixParser.ts b/src/core/datamatrix/decoder/BitMatrixParser.ts
index ea235a0d..eadb901f 100644
--- a/src/core/datamatrix/decoder/BitMatrixParser.ts
+++ b/src/core/datamatrix/decoder/BitMatrixParser.ts
@@ -32,7 +32,7 @@ export default class BitMatrixParser {
/**
* @param bitMatrix {@link BitMatrix} to parse
* @throws FormatException if dimension is < 8 or > 144 or not 0 mod 2
- */
+ */
constructor(bitMatrix: BitMatrix) {
const dimension = bitMatrix.getHeight();
if (dimension < 8 || dimension > 144 || (dimension & 0x01) !== 0) {
@@ -58,7 +58,7 @@ export default class BitMatrixParser {
* @return {@link Version} encapsulating the Data Matrix Code's "version"
* @throws FormatException if the dimensions of the mapping matrix are not valid
* Data Matrix dimensions.
- */
+ */
public static readVersion(bitMatrix: BitMatrix): Version {
const numRows = bitMatrix.getHeight();
const numColumns = bitMatrix.getWidth();
@@ -72,7 +72,7 @@ export default class BitMatrixParser {
*
* @return bytes encoded within the Data Matrix Code
* @throws FormatException if the exact number of bytes expected is not read
- */
+ */
readCodewords(): Int8Array {
const result = new Int8Array(this.version.getTotalCodewords());
@@ -127,7 +127,7 @@ export default class BitMatrixParser {
// Sweep downward diagonally to the left
do {
if ((row >= 0) && (column < numColumns) && !this.readMappingMatrix.get(column, row)) {
- result[resultOffset++] = this.readUtah(row, column, numRows, numColumns) & 0xff;
+ result[resultOffset++] = this.readUtah(row, column, numRows, numColumns) & 0xff;
}
row += 2;
column -= 2;
@@ -151,7 +151,7 @@ export default class BitMatrixParser {
* @param numRows Number of rows in the mapping matrix
* @param numColumns Number of columns in the mapping matrix
* @return value of the given bit in the mapping matrix
- */
+ */
private readModule(row: number, column: number, numRows: number, numColumns: number): boolean {
// Adjust the row and column indices based on boundary wrapping
if (row < 0) {
@@ -176,7 +176,7 @@ export default class BitMatrixParser {
* @param numRows Number of rows in the mapping matrix
* @param numColumns Number of columns in the mapping matrix
* @return byte from the utah shape
- */
+ */
private readUtah(row: number, column: number, numRows: number, numColumns: number): number {
let currentByte = 0;
if (this.readModule(row - 2, column - 2, numRows, numColumns)) {
@@ -221,7 +221,7 @@ export default class BitMatrixParser {
* @param numRows Number of rows in the mapping matrix
* @param numColumns Number of columns in the mapping matrix
* @return byte from the Corner condition 1
- */
+ */
private readCorner1(numRows: number, numColumns: number): number {
let currentByte = 0;
if (this.readModule(numRows - 1, 0, numRows, numColumns)) {
@@ -266,7 +266,7 @@ export default class BitMatrixParser {
* @param numRows Number of rows in the mapping matrix
* @param numColumns Number of columns in the mapping matrix
* @return byte from the Corner condition 2
- */
+ */
private readCorner2(numRows: number, numColumns: number): number {
let currentByte = 0;
if (this.readModule(numRows - 3, 0, numRows, numColumns)) {
@@ -311,7 +311,7 @@ export default class BitMatrixParser {
* @param numRows Number of rows in the mapping matrix
* @param numColumns Number of columns in the mapping matrix
* @return byte from the Corner condition 3
- */
+ */
private readCorner3(numRows: number, numColumns: number): number {
let currentByte = 0;
if (this.readModule(numRows - 1, 0, numRows, numColumns)) {
@@ -356,7 +356,7 @@ export default class BitMatrixParser {
* @param numRows Number of rows in the mapping matrix
* @param numColumns Number of columns in the mapping matrix
* @return byte from the Corner condition 4
- */
+ */
private readCorner4(numRows: number, numColumns: number): number {
let currentByte = 0;
if (this.readModule(numRows - 3, 0, numRows, numColumns)) {
@@ -399,7 +399,7 @@ export default class BitMatrixParser {
*
* @param bitMatrix Original {@link BitMatrix} with alignment patterns
* @return BitMatrix that has the alignment patterns removed
- */
+ */
private extractDataRegion(bitMatrix: BitMatrix): BitMatrix {
const symbolSizeRows = this.version.getSymbolSizeRows();
const symbolSizeColumns = this.version.getSymbolSizeColumns();
diff --git a/src/core/datamatrix/decoder/DataBlock.ts b/src/core/datamatrix/decoder/DataBlock.ts
index 9e686fee..f27ea6a2 100644
--- a/src/core/datamatrix/decoder/DataBlock.ts
+++ b/src/core/datamatrix/decoder/DataBlock.ts
@@ -44,9 +44,9 @@ export default class DataBlock {
* @param version version of the Data Matrix Code
* @return DataBlocks containing original bytes, "de-interleaved" from representation in the
* Data Matrix Code
- */
+ */
static getDataBlocks(rawCodewords: Int8Array,
- version: Version): DataBlock[] {
+ version: Version): DataBlock[] {
// Figure out the number and size of data blocks used by this version
const ecBlocks = version.getECBlocks();
@@ -54,7 +54,7 @@ export default class DataBlock {
let totalBlocks = 0;
const ecBlockArray = ecBlocks.getECBlocks();
for (let ecBlock of ecBlockArray) {
- totalBlocks += ecBlock.getCount();
+ totalBlocks += ecBlock.getCount();
}
// Now establish DataBlocks of the appropriate size and number of data codewords
diff --git a/src/core/datamatrix/decoder/DecodedBitStreamParser.ts b/src/core/datamatrix/decoder/DecodedBitStreamParser.ts
index 9f801292..edecf16c 100644
--- a/src/core/datamatrix/decoder/DecodedBitStreamParser.ts
+++ b/src/core/datamatrix/decoder/DecodedBitStreamParser.ts
@@ -47,7 +47,7 @@ export default class DecodedBitStreamParser {
/**
* See ISO 16022:2006, Annex C Table C.1
* The C40 Basic Character Set (*'s used for placeholders for the shift values)
- */
+ */
private static C40_BASIC_SET_CHARS: string[] = [
'*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
@@ -55,14 +55,14 @@ export default class DecodedBitStreamParser {
];
private static C40_SHIFT2_SET_CHARS: string[] = [
- '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.',
- '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_'
+ '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.',
+ '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_'
];
/**
* See ISO 16022:2006, Annex C Table C.2
* The Text Basic Character Set (*'s used for placeholders for the shift values)
- */
+ */
private static TEXT_BASIC_SET_CHARS: string[] = [
'*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
@@ -74,10 +74,10 @@ export default class DecodedBitStreamParser {
private static TEXT_SHIFT3_SET_CHARS: string[] = [
'`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
- 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', String.fromCharCode(127)
+ 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', String.fromCharCode(127)
];
- static decode(bytes: Uint8Array): DecoderResult {
+ static decode(bytes: Uint8Array): DecoderResult {
const bits = new BitSource(bytes);
const result = new StringBuilder();
const resultTrailer = new StringBuilder();
@@ -117,10 +117,10 @@ export default class DecodedBitStreamParser {
/**
* See ISO 16022:2006, 5.2.3 and Annex C, Table C.2
- */
+ */
private static decodeAsciiSegment(bits: BitSource,
- result: StringBuilder,
- resultTrailer: StringBuilder): Mode {
+ result: StringBuilder,
+ resultTrailer: StringBuilder): Mode {
let upperShift = false;
do {
let oneByte = bits.readBits(8);
@@ -160,11 +160,11 @@ export default class DecodedBitStreamParser {
break;
case 236: // 05 Macro
result.append('[)>\u001E05\u001D');
- resultTrailer.insert(0, '\u001E\u0004');
+ resultTrailer.insert(0, '\u001E\u0004', 2); // Replacing two characters
break;
case 237: // 06 Macro
result.append('[)>\u001E06\u001D');
- resultTrailer.insert(0, '\u001E\u0004');
+ resultTrailer.insert(0, '\u001E\u0004', 2); // Replacing two characters
break;
case 238: // Latch to ANSI X12 encodation
return Mode.ANSIX12_ENCODE;
@@ -192,7 +192,7 @@ export default class DecodedBitStreamParser {
/**
* See ISO 16022:2006, 5.2.5 and Annex C, Table C.1
- */
+ */
private static decodeC40Segment(bits: BitSource, result: StringBuilder): void {
// Three C40 values are encoded in a 16-bit value as
// (1600 * C1) + (40 * C2) + C3 + 1
@@ -258,7 +258,7 @@ export default class DecodedBitStreamParser {
upperShift = true;
break;
default:
- throw new FormatException();
+ throw new FormatException();
}
}
shift = 0;
@@ -281,7 +281,7 @@ export default class DecodedBitStreamParser {
/**
* See ISO 16022:2006, 5.2.6 and Annex C, Table C.2
- */
+ */
private static decodeTextSegment(bits: BitSource, result: StringBuilder): void {
// Three Text values are encoded in a 16-bit value as
// (1600 * C1) + (40 * C2) + C3 + 1
@@ -348,7 +348,7 @@ export default class DecodedBitStreamParser {
upperShift = true;
break;
default:
- throw new FormatException();
+ throw new FormatException();
}
}
shift = 0;
@@ -368,7 +368,7 @@ export default class DecodedBitStreamParser {
}
break;
default:
- throw new FormatException();
+ throw new FormatException();
}
}
} while (bits.available() > 0);
@@ -376,9 +376,9 @@ export default class DecodedBitStreamParser {
/**
* See ISO 16022:2006, 5.2.7
- */
+ */
private static decodeAnsiX12Segment(bits: BitSource,
- result: StringBuilder): void {
+ result: StringBuilder): void {
// Three ANSI X12 values are encoded in a 16-bit value as
// (1600 * C1) + (40 * C2) + C3 + 1
@@ -436,7 +436,7 @@ export default class DecodedBitStreamParser {
/**
* See ISO 16022:2006, 5.2.8 and Annex C Table C.3
- */
+ */
private static decodeEdifactSegment(bits: BitSource, result: StringBuilder): void {
do {
// If there is only two or less bytes left then it will be encoded as ASCII
@@ -467,10 +467,10 @@ export default class DecodedBitStreamParser {
/**
* See ISO 16022:2006, 5.2.9 and Annex B, B.2
- */
+ */
private static decodeBase256Segment(bits: BitSource,
- result: StringBuilder,
- byteSegments: Uint8Array[]): void {
+ result: StringBuilder,
+ byteSegments: Uint8Array[]): void {
// Figure out how long the Base 256 Segment is.
let codewordPosition = 1 + bits.getByteOffset(); // position is 1-indexed
const d1 = this.unrandomize255State(bits.readBits(8), codewordPosition++);
@@ -507,9 +507,9 @@ export default class DecodedBitStreamParser {
/**
* See ISO 16022:2006, Annex B, B.2
- */
+ */
private static unrandomize255State(randomizedBase256Codeword: number,
- base256CodewordPosition: number): number {
+ base256CodewordPosition: number): number {
const pseudoRandomNumber = ((149 * base256CodewordPosition) % 255) + 1;
const tempVariable = randomizedBase256Codeword - pseudoRandomNumber;
return tempVariable >= 0 ? tempVariable : tempVariable + 256;
diff --git a/src/core/datamatrix/decoder/Decoder.ts b/src/core/datamatrix/decoder/Decoder.ts
index e2b933d9..c22c690d 100644
--- a/src/core/datamatrix/decoder/Decoder.ts
+++ b/src/core/datamatrix/decoder/Decoder.ts
@@ -45,7 +45,7 @@ export default class Decoder {
* @return text and bytes encoded within the Data Matrix Code
* @throws FormatException if the Data Matrix Code cannot be decoded
* @throws ChecksumException if error correction fails
- */
+ */
public decode(bits: BitMatrix): DecoderResult {
// Construct a parser and read version, error-correction level
const parser = new BitMatrixParser(bits);
@@ -87,7 +87,7 @@ export default class Decoder {
* @param codewordBytes data and error correction codewords
* @param numDataCodewords number of codewords that are data bytes
* @throws ChecksumException if error correction fails
- */
+ */
private correctErrors(codewordBytes: Uint8Array, numDataCodewords: number): void {
// const numCodewords = codewordBytes.length;
// First read into an array of ints
diff --git a/src/core/datamatrix/decoder/Version.ts b/src/core/datamatrix/decoder/Version.ts
index 7c413249..9aa86e7f 100644
--- a/src/core/datamatrix/decoder/Version.ts
+++ b/src/core/datamatrix/decoder/Version.ts
@@ -18,53 +18,53 @@ import FormatException from '../../FormatException';
*/
- /**
- * Encapsulates a set of error-correction blocks in one symbol version. Most versions will
- * use blocks of differing sizes within one version, so, this encapsulates the parameters for
- * each set of blocks. It also holds the number of error-correction codewords per block since it
- * will be the same across all blocks within one version.
- */
- export class ECBlocks {
- private ecCodewords: number;
- private ecBlocks: ECB[];
-
- constructor(ecCodewords: number, ecBlocks1: ECB, ecBlocks2?: ECB) {
- this.ecCodewords = ecCodewords;
- this.ecBlocks = [ ecBlocks1 ];
- ecBlocks2 && this.ecBlocks.push(ecBlocks2);
- }
+/**
+ * Encapsulates a set of error-correction blocks in one symbol version. Most versions will
+ * use blocks of differing sizes within one version, so, this encapsulates the parameters for
+ * each set of blocks. It also holds the number of error-correction codewords per block since it
+ * will be the same across all blocks within one version.
+ */
+export class ECBlocks {
+ private ecCodewords: number;
+ private ecBlocks: ECB[];
+
+ constructor(ecCodewords: number, ecBlocks1: ECB, ecBlocks2?: ECB) {
+ this.ecCodewords = ecCodewords;
+ this.ecBlocks = [ecBlocks1];
+ ecBlocks2 && this.ecBlocks.push(ecBlocks2);
+ }
- getECCodewords(): number {
- return this.ecCodewords;
- }
+ getECCodewords(): number {
+ return this.ecCodewords;
+ }
- getECBlocks(): ECB[] {
- return this.ecBlocks;
- }
+ getECBlocks(): ECB[] {
+ return this.ecBlocks;
}
+}
- /**
- * Encapsulates the parameters for one error-correction block in one symbol version.
- * This includes the number of data codewords, and the number of times a block with these
- * parameters is used consecutively in the Data Matrix code version's format.
- */
+/**
+ * Encapsulates the parameters for one error-correction block in one symbol version.
+ * This includes the number of data codewords, and the number of times a block with these
+ * parameters is used consecutively in the Data Matrix code version's format.
+ */
export class ECB {
- private count: number;
- private dataCodewords: number;
+ private count: number;
+ private dataCodewords: number;
- constructor(count: number, dataCodewords: number) {
- this.count = count;
- this.dataCodewords = dataCodewords;
- }
+ constructor(count: number, dataCodewords: number) {
+ this.count = count;
+ this.dataCodewords = dataCodewords;
+ }
- getCount(): number {
- return this.count;
- }
+ getCount(): number {
+ return this.count;
+ }
- getDataCodewords(): number {
- return this.dataCodewords;
- }
+ getDataCodewords(): number {
+ return this.dataCodewords;
}
+}
/**
* The Version object encapsulates attributes about a particular
@@ -85,11 +85,11 @@ export default class Version {
private totalCodewords: number;
constructor(versionNumber,
- symbolSizeRows,
- symbolSizeColumns,
- dataRegionSizeRows,
- dataRegionSizeColumns,
- ecBlocks: ECBlocks) {
+ symbolSizeRows,
+ symbolSizeColumns,
+ dataRegionSizeRows,
+ dataRegionSizeColumns,
+ ecBlocks: ECBlocks) {
this.versionNumber = versionNumber;
this.symbolSizeRows = symbolSizeRows;
this.symbolSizeColumns = symbolSizeColumns;
@@ -142,7 +142,7 @@ export default class Version {
* @param numColumns Number of columns in modules
* @return Version for a Data Matrix Code of those dimensions
* @throws FormatException if dimensions do correspond to a valid Data Matrix size
- */
+ */
public static getVersionForDimensions(numRows: number, numColumns: number): Version {
if ((numRows & 0x01) !== 0 || (numColumns & 0x01) !== 0) {
throw new FormatException();
@@ -157,77 +157,77 @@ export default class Version {
throw new FormatException();
}
-// @Override
+ // @Override
public toString(): string {
return '' + this.versionNumber;
}
/**
* See ISO 16022:2006 5.5.1 Table 7
- */
+ */
private static buildVersions(): Version[] {
return [
- new Version(1, 10, 10, 8, 8,
- new ECBlocks(5, new ECB(1, 3))),
- new Version(2, 12, 12, 10, 10,
- new ECBlocks(7, new ECB(1, 5))),
- new Version(3, 14, 14, 12, 12,
- new ECBlocks(10, new ECB(1, 8))),
- new Version(4, 16, 16, 14, 14,
- new ECBlocks(12, new ECB(1, 12))),
- new Version(5, 18, 18, 16, 16,
- new ECBlocks(14, new ECB(1, 18))),
- new Version(6, 20, 20, 18, 18,
- new ECBlocks(18, new ECB(1, 22))),
- new Version(7, 22, 22, 20, 20,
- new ECBlocks(20, new ECB(1, 30))),
- new Version(8, 24, 24, 22, 22,
- new ECBlocks(24, new ECB(1, 36))),
- new Version(9, 26, 26, 24, 24,
- new ECBlocks(28, new ECB(1, 44))),
- new Version(10, 32, 32, 14, 14,
- new ECBlocks(36, new ECB(1, 62))),
- new Version(11, 36, 36, 16, 16,
- new ECBlocks(42, new ECB(1, 86))),
- new Version(12, 40, 40, 18, 18,
- new ECBlocks(48, new ECB(1, 114))),
- new Version(13, 44, 44, 20, 20,
- new ECBlocks(56, new ECB(1, 144))),
- new Version(14, 48, 48, 22, 22,
- new ECBlocks(68, new ECB(1, 174))),
- new Version(15, 52, 52, 24, 24,
- new ECBlocks(42, new ECB(2, 102))),
- new Version(16, 64, 64, 14, 14,
- new ECBlocks(56, new ECB(2, 140))),
- new Version(17, 72, 72, 16, 16,
- new ECBlocks(36, new ECB(4, 92))),
- new Version(18, 80, 80, 18, 18,
- new ECBlocks(48, new ECB(4, 114))),
- new Version(19, 88, 88, 20, 20,
- new ECBlocks(56, new ECB(4, 144))),
- new Version(20, 96, 96, 22, 22,
- new ECBlocks(68, new ECB(4, 174))),
- new Version(21, 104, 104, 24, 24,
- new ECBlocks(56, new ECB(6, 136))),
- new Version(22, 120, 120, 18, 18,
- new ECBlocks(68, new ECB(6, 175))),
- new Version(23, 132, 132, 20, 20,
- new ECBlocks(62, new ECB(8, 163))),
- new Version(24, 144, 144, 22, 22,
- new ECBlocks(62, new ECB(8, 156), new ECB(2, 155))),
- new Version(25, 8, 18, 6, 16,
- new ECBlocks(7, new ECB(1, 5))),
- new Version(26, 8, 32, 6, 14,
- new ECBlocks(11, new ECB(1, 10))),
- new Version(27, 12, 26, 10, 24,
- new ECBlocks(14, new ECB(1, 16))),
- new Version(28, 12, 36, 10, 16,
- new ECBlocks(18, new ECB(1, 22))),
- new Version(29, 16, 36, 14, 16,
- new ECBlocks(24, new ECB(1, 32))),
- new Version(30, 16, 48, 14, 22,
- new ECBlocks(28, new ECB(1, 49)))
- ];
+ new Version(1, 10, 10, 8, 8,
+ new ECBlocks(5, new ECB(1, 3))),
+ new Version(2, 12, 12, 10, 10,
+ new ECBlocks(7, new ECB(1, 5))),
+ new Version(3, 14, 14, 12, 12,
+ new ECBlocks(10, new ECB(1, 8))),
+ new Version(4, 16, 16, 14, 14,
+ new ECBlocks(12, new ECB(1, 12))),
+ new Version(5, 18, 18, 16, 16,
+ new ECBlocks(14, new ECB(1, 18))),
+ new Version(6, 20, 20, 18, 18,
+ new ECBlocks(18, new ECB(1, 22))),
+ new Version(7, 22, 22, 20, 20,
+ new ECBlocks(20, new ECB(1, 30))),
+ new Version(8, 24, 24, 22, 22,
+ new ECBlocks(24, new ECB(1, 36))),
+ new Version(9, 26, 26, 24, 24,
+ new ECBlocks(28, new ECB(1, 44))),
+ new Version(10, 32, 32, 14, 14,
+ new ECBlocks(36, new ECB(1, 62))),
+ new Version(11, 36, 36, 16, 16,
+ new ECBlocks(42, new ECB(1, 86))),
+ new Version(12, 40, 40, 18, 18,
+ new ECBlocks(48, new ECB(1, 114))),
+ new Version(13, 44, 44, 20, 20,
+ new ECBlocks(56, new ECB(1, 144))),
+ new Version(14, 48, 48, 22, 22,
+ new ECBlocks(68, new ECB(1, 174))),
+ new Version(15, 52, 52, 24, 24,
+ new ECBlocks(42, new ECB(2, 102))),
+ new Version(16, 64, 64, 14, 14,
+ new ECBlocks(56, new ECB(2, 140))),
+ new Version(17, 72, 72, 16, 16,
+ new ECBlocks(36, new ECB(4, 92))),
+ new Version(18, 80, 80, 18, 18,
+ new ECBlocks(48, new ECB(4, 114))),
+ new Version(19, 88, 88, 20, 20,
+ new ECBlocks(56, new ECB(4, 144))),
+ new Version(20, 96, 96, 22, 22,
+ new ECBlocks(68, new ECB(4, 174))),
+ new Version(21, 104, 104, 24, 24,
+ new ECBlocks(56, new ECB(6, 136))),
+ new Version(22, 120, 120, 18, 18,
+ new ECBlocks(68, new ECB(6, 175))),
+ new Version(23, 132, 132, 20, 20,
+ new ECBlocks(62, new ECB(8, 163))),
+ new Version(24, 144, 144, 22, 22,
+ new ECBlocks(62, new ECB(8, 156), new ECB(2, 155))),
+ new Version(25, 8, 18, 6, 16,
+ new ECBlocks(7, new ECB(1, 5))),
+ new Version(26, 8, 32, 6, 14,
+ new ECBlocks(11, new ECB(1, 10))),
+ new Version(27, 12, 26, 10, 24,
+ new ECBlocks(14, new ECB(1, 16))),
+ new Version(28, 12, 36, 10, 16,
+ new ECBlocks(18, new ECB(1, 22))),
+ new Version(29, 16, 36, 14, 16,
+ new ECBlocks(24, new ECB(1, 32))),
+ new Version(30, 16, 48, 14, 22,
+ new ECBlocks(28, new ECB(1, 49)))
+ ];
}
}
diff --git a/src/core/datamatrix/detector/Detector.ts b/src/core/datamatrix/detector/Detector.ts
index ff6c133c..c668643c 100644
--- a/src/core/datamatrix/detector/Detector.ts
+++ b/src/core/datamatrix/detector/Detector.ts
@@ -44,7 +44,7 @@ export default class Detector {
*
* @return {@link DetectorResult} encapsulating results of detecting a Data Matrix Code
* @throws NotFoundException if no Data Matrix Code can be found
- */
+ */
public detect(): DetectorResult {
@@ -54,7 +54,7 @@ export default class Detector {
points = this.detectSolid2(points);
points[3] = this.correctTopRight(points);
if (!points[3]) {
- throw new NotFoundException();
+ throw new NotFoundException();
}
points = this.shiftToModuleCenter(points);
@@ -78,12 +78,12 @@ export default class Detector {
}
let bits = Detector.sampleGrid(this.image,
- topLeft,
- bottomLeft,
- bottomRight,
- topRight,
- dimensionTop,
- dimensionRight);
+ topLeft,
+ bottomLeft,
+ bottomRight,
+ topRight,
+ dimensionTop,
+ dimensionRight);
return new DetectorResult(bits, [topLeft, bottomLeft, bottomRight, topRight]);
}
@@ -115,7 +115,7 @@ export default class Detector {
/**
* Detect a solid side which has minimum transition.
- */
+ */
private detectSolid1(cornerPoints: ResultPoint[]): ResultPoint[] {
// 0 2
// 1 3
@@ -160,7 +160,7 @@ export default class Detector {
/**
* Detect a second solid side next to first solid side.
- */
+ */
private detectSolid2(points: ResultPoint[]): ResultPoint[] {
// A..D
// : :
@@ -200,7 +200,7 @@ export default class Detector {
/**
* Calculates the corner position of the white top right module.
- */
+ */
private correctTopRight(points: ResultPoint[]): ResultPoint {
// A..D
// | :
@@ -222,7 +222,7 @@ export default class Detector {
let candidate1 = new ResultPoint(
pointD.getX() + (pointC.getX() - pointB.getX()) / (trTop + 1),
pointD.getY() + (pointC.getY() - pointB.getY()) / (trTop + 1));
- let candidate2 = new ResultPoint(
+ let candidate2 = new ResultPoint(
pointD.getX() + (pointA.getX() - pointB.getX()) / (trRight + 1),
pointD.getY() + (pointA.getY() - pointB.getY()) / (trRight + 1));
@@ -248,7 +248,7 @@ export default class Detector {
/**
* Shift the edge points to the module center.
- */
+ */
private shiftToModuleCenter(points: ResultPoint[]): ResultPoint[] {
// A..D
// | :
@@ -306,39 +306,39 @@ export default class Detector {
}
private static sampleGrid(image: BitMatrix,
- topLeft: ResultPoint,
- bottomLeft: ResultPoint,
- bottomRight: ResultPoint,
- topRight: ResultPoint,
- dimensionX: int,
- dimensionY: int): BitMatrix {
+ topLeft: ResultPoint,
+ bottomLeft: ResultPoint,
+ bottomRight: ResultPoint,
+ topRight: ResultPoint,
+ dimensionX: int,
+ dimensionY: int): BitMatrix {
const sampler = GridSamplerInstance.getInstance();
return sampler.sampleGrid(image,
- dimensionX,
- dimensionY,
- 0.5,
- 0.5,
- dimensionX - 0.5,
- 0.5,
- dimensionX - 0.5,
- dimensionY - 0.5,
- 0.5,
- dimensionY - 0.5,
- topLeft.getX(),
- topLeft.getY(),
- topRight.getX(),
- topRight.getY(),
- bottomRight.getX(),
- bottomRight.getY(),
- bottomLeft.getX(),
- bottomLeft.getY());
+ dimensionX,
+ dimensionY,
+ 0.5,
+ 0.5,
+ dimensionX - 0.5,
+ 0.5,
+ dimensionX - 0.5,
+ dimensionY - 0.5,
+ 0.5,
+ dimensionY - 0.5,
+ topLeft.getX(),
+ topLeft.getY(),
+ topRight.getX(),
+ topRight.getY(),
+ bottomRight.getX(),
+ bottomRight.getY(),
+ bottomLeft.getX(),
+ bottomLeft.getY());
}
/**
* Counts the number of black/white transitions between two points, using something like Bresenham's algorithm.
- */
+ */
private transitionsBetween(from: ResultPoint, to: ResultPoint): int {
// See QR Code Detector, sizeOfBlackWhiteBlackRun()
let fromX = Math.trunc(from.getX());
diff --git a/src/core/multi/MultipleBarcodeReader.ts b/src/core/multi/MultipleBarcodeReader.ts
index b8d7c4e6..56184045 100644
--- a/src/core/multi/MultipleBarcodeReader.ts
+++ b/src/core/multi/MultipleBarcodeReader.ts
@@ -32,16 +32,16 @@ import Result from '../Result';
* @see com.google.zxing.Reader
* @author Sean Owen
*/
-export default /*public*/ interface MultipleBarcodeReader {
+export default /* public */ interface MultipleBarcodeReader {
/**
* @throws NotFoundException
- */
+ */
decodeMultiple(image: BinaryBitmap): Result[];
/**
* @throws NotFoundException
- */
+ */
decodeMultiple(image: BinaryBitmap, hints: Map): Result[];
}
diff --git a/src/core/multi/qrcode/QRCodeMultiReader.ts b/src/core/multi/qrcode/QRCodeMultiReader.ts
new file mode 100644
index 00000000..71e3a227
--- /dev/null
+++ b/src/core/multi/qrcode/QRCodeMultiReader.ts
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2009 ZXing authors
+ *
+ * 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 { int, List } from '../../../customTypings';
+import BarcodeFormat from '../../BarcodeFormat';
+import BinaryBitmap from '../../BinaryBitmap';
+import DecoderResult from '../../common/DecoderResult';
+import DetectorResult from '../../common/DetectorResult';
+import DecodeHintType from '../../DecodeHintType';
+import QRCodeDecoderMetaData from '../../qrcode/decoder/QRCodeDecoderMetaData';
+import QRCodeReader from '../../qrcode/QRCodeReader';
+import ReaderException from '../../ReaderException';
+import Result from '../../Result';
+import ResultMetadataType from '../../ResultMetadataType';
+import ResultPoint from '../../ResultPoint';
+import ByteArrayOutputStream from '../../util/ByteArrayOutputStream';
+import Collections from '../../util/Collections';
+import Comparator from '../../util/Comparator';
+import Integer from '../../util/Integer';
+import StringBuilder from '../../util/StringBuilder';
+import MultipleBarcodeReader from '../MultipleBarcodeReader';
+import MultiDetector from './detector/MultiDetector';
+
+// package com.google.zxing.multi.qrcode;
+
+// import com.google.zxing.BarcodeFormat;
+// import com.google.zxing.BinaryBitmap;
+// import com.google.zxing.DecodeHintType;
+// import com.google.zxing.NotFoundException;
+// import com.google.zxing.ReaderException;
+// import com.google.zxing.Result;
+// import com.google.zxing.ResultMetadataType;
+// import com.google.zxing.ResultPoint;
+// import com.google.zxing.common.DecoderResult;
+// import com.google.zxing.common.DetectorResult;
+// import com.google.zxing.multi.MultipleBarcodeReader;
+// import com.google.zxing.multi.qrcode.detector.MultiDetector;
+// import com.google.zxing.qrcode.QRCodeReader;
+// import com.google.zxing.qrcode.decoder.QRCodeDecoderMetaData;
+
+// import java.io.ByteArrayOutputStream;
+// import java.io.Serializable;
+// import java.util.ArrayList;
+// import java.util.List;
+// import java.util.Map;
+// import java.util.Collections;
+// import java.util.Comparator;
+
+/**
+ * This implementation can detect and decode multiple QR Codes in an image.
+ *
+ * @author Sean Owen
+ * @author Hannes Erven
+ */
+export default /*public final*/ class QRCodeMultiReader extends QRCodeReader implements MultipleBarcodeReader {
+
+ private static /* final */ EMPTY_RESULT_ARRAY: Result[] = [];
+ protected static /* final */ NO_POINTS = new Array();
+
+ /**
+ * TYPESCRIPTPORT: this is an overloaded method so here it'll work only as a entrypoint for choosing which overload to call.
+ */
+ public decodeMultiple(image: BinaryBitmap, hints: Map = null): Result[] {
+
+ if (hints && hints instanceof Map) {
+ return this.decodeMultipleImpl(image, hints);
+ }
+
+ return this.decodeMultipleOverload1(image);
+ }
+
+ /**
+ * @throws NotFoundException
+ * @override decodeMultiple
+ */
+ private decodeMultipleOverload1(image: BinaryBitmap): Result[] {
+ return this.decodeMultipleImpl(image, null);
+ }
+
+ /**
+ * @override
+ * @throws NotFoundException
+ */
+ private decodeMultipleImpl(image: BinaryBitmap, hints: Map): Result[] {
+ let results: List = [];
+ const detectorResults: DetectorResult[] = new MultiDetector(image.getBlackMatrix()).detectMulti(hints);
+ for (const detectorResult of detectorResults) {
+ try {
+ const decoderResult: DecoderResult = this.getDecoder().decodeBitMatrix(detectorResult.getBits(), hints);
+ const points: ResultPoint[] = detectorResult.getPoints();
+ // If the code was mirrored: swap the bottom-left and the top-right points.
+ if (decoderResult.getOther() instanceof QRCodeDecoderMetaData) {
+ ( decoderResult.getOther()).applyMirroredCorrection(points);
+ }
+ const result: Result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points,
+ BarcodeFormat.QR_CODE);
+ const byteSegments: List = decoderResult.getByteSegments();
+ if (byteSegments != null) {
+ result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
+ }
+ const ecLevel: string = decoderResult.getECLevel();
+ if (ecLevel != null) {
+ result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
+ }
+ if (decoderResult.hasStructuredAppend()) {
+ result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE,
+ decoderResult.getStructuredAppendSequenceNumber());
+ result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_PARITY,
+ decoderResult.getStructuredAppendParity());
+ }
+ results.push(result);
+ } catch (re) {
+ if (re instanceof ReaderException) {
+ // ignore and continue
+ } else {
+ throw re;
+ }
+ }
+ }
+ if (results.length === 0) {
+ return QRCodeMultiReader.EMPTY_RESULT_ARRAY;
+ } else {
+ results = QRCodeMultiReader.processStructuredAppend(results);
+ return results/* .toArray(QRCodeMultiReader.EMPTY_RESULT_ARRAY) */;
+ }
+ }
+
+ static processStructuredAppend( results: List): List {
+ const newResults: List = [];
+ const saResults: List = [];
+ for (const result of results) {
+ if (result.getResultMetadata().has(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE)) {
+ saResults.push(result);
+ } else {
+ newResults.push(result);
+ }
+ }
+ if (saResults.length === 0) {
+ return results;
+ }
+
+ // sort and concatenate the SA list items
+ Collections.sort(saResults, new SAComparator());
+ const newText: StringBuilder = new StringBuilder();
+ const newRawBytes: ByteArrayOutputStream = new ByteArrayOutputStream();
+ const newByteSegment: ByteArrayOutputStream = new ByteArrayOutputStream();
+ for (const saResult of saResults) {
+ newText.append(saResult.getText());
+ const saBytes: Uint8Array = saResult.getRawBytes();
+ newRawBytes.writeBytesOffset(saBytes, 0, saBytes.length);
+ // @SuppressWarnings("unchecked")
+ const byteSegments: Iterable =
+ > saResult.getResultMetadata().get(ResultMetadataType.BYTE_SEGMENTS);
+ if (byteSegments != null) {
+ for (const segment of byteSegments) {
+ newByteSegment.writeBytesOffset(segment, 0, segment.length);
+ }
+ }
+ }
+
+ const newResult: Result = new Result(newText.toString(), newRawBytes.toByteArray(), QRCodeMultiReader.NO_POINTS, BarcodeFormat.QR_CODE);
+ if (newByteSegment.size() > 0) {
+ newResult.putMetadata(ResultMetadataType.BYTE_SEGMENTS, Collections.singletonList(newByteSegment.toByteArray()));
+ }
+ newResults.push(newResult); // TYPESCRIPTPORT: inserted element at the start of the array because it seems the Java version does that as well.
+ return newResults;
+ }
+
+}
+
+/* private static final*/ class SAComparator implements Comparator/*, Serializable*/ {
+ /**
+ * @override
+ */
+ public compare(a: Result, b: Result): int {
+ const aNumber: int = a.getResultMetadata().get(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE);
+ const bNumber: int = b.getResultMetadata().get(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE);
+ return Integer.compare(aNumber, bNumber);
+ }
+}
diff --git a/src/core/multi/qrcode/detector/MultiDetector.ts b/src/core/multi/qrcode/detector/MultiDetector.ts
new file mode 100644
index 00000000..f669a4af
--- /dev/null
+++ b/src/core/multi/qrcode/detector/MultiDetector.ts
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2009 ZXing authors
+ *
+ * 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 BitMatrix from '../../../common/BitMatrix';
+import DetectorResult from '../../../common/DetectorResult';
+import DecodeHintType from '../../../DecodeHintType';
+import NotFoundException from '../../../NotFoundException';
+import Detector from '../../../qrcode/detector/Detector';
+import FinderPatternInfo from '../../../qrcode/detector/FinderPatternInfo';
+import ReaderException from '../../../ReaderException';
+import ResultPointCallback from '../../../ResultPointCallback';
+import { List } from '../../../../customTypings';
+import MultiFinderPatternFinder from './MultiFinderPatternFinder';
+
+// package com.google.zxing.multi.qrcode.detector;
+
+// import com.google.zxing.DecodeHintType;
+// import com.google.zxing.NotFoundException;
+// import com.google.zxing.ReaderException;
+// import com.google.zxing.ResultPointCallback;
+// import com.google.zxing.common.BitMatrix;
+// import com.google.zxing.common.DetectorResult;
+// import com.google.zxing.qrcode.detector.Detector;
+// import com.google.zxing.qrcode.detector.FinderPatternInfo;
+
+// import java.util.ArrayList;
+// import java.util.List;
+// import java.util.Map;
+
+/**
+ * Encapsulates logic that can detect one or more QR Codes in an image, even if the QR Code
+ * is rotated or skewed, or partially obscured.
+ *
+ * @author Sean Owen
+ * @author Hannes Erven
+ */
+export default /* public final */ class MultiDetector extends Detector {
+
+ private static /* final */ EMPTY_DETECTOR_RESULTS: DetectorResult[] = [];
+
+ public constructor( image: BitMatrix) {
+ super(image);
+ }
+
+ /** @throws NotFoundException */
+ public detectMulti(hints: Map): DetectorResult[] {
+ const image: BitMatrix = this.getImage();
+ const resultPointCallback: ResultPointCallback =
+ hints == null ? null : hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
+ const finder: MultiFinderPatternFinder = new MultiFinderPatternFinder(image, resultPointCallback);
+ const infos: FinderPatternInfo[] = finder.findMulti(hints);
+
+ if (infos.length === 0) {
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ const result: List = [];
+ for (const info of infos) {
+ try {
+ result.push(this.processFinderPatternInfo(info));
+ } catch (e) {
+ if (e instanceof ReaderException) {
+ // ignore
+ } else {
+ throw e;
+ }
+ }
+ }
+ if (result.length === 0) {
+ return MultiDetector.EMPTY_DETECTOR_RESULTS;
+ } else {
+ return result/* .toArray(EMPTY_DETECTOR_RESULTS) */;
+ }
+ }
+
+}
diff --git a/src/core/multi/qrcode/detector/MultiFinderPatternFinder.ts b/src/core/multi/qrcode/detector/MultiFinderPatternFinder.ts
new file mode 100644
index 00000000..6d6dbba9
--- /dev/null
+++ b/src/core/multi/qrcode/detector/MultiFinderPatternFinder.ts
@@ -0,0 +1,300 @@
+/*
+ * Copyright 2009 ZXing authors
+ *
+ * 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 BitMatrix from '../../../common/BitMatrix';
+import DecodeHintType from '../../../DecodeHintType';
+import NotFoundException from '../../../NotFoundException';
+import FinderPattern from '../../../qrcode/detector/FinderPattern';
+import FinderPatternFinder from '../../../qrcode/detector/FinderPatternFinder';
+import FinderPatternInfo from '../../../qrcode/detector/FinderPatternInfo';
+import ResultPoint from '../../../ResultPoint';
+import ResultPointCallback from '../../../ResultPointCallback';
+import Collections from '../../../util/Collections';
+import Comparator from '../../../util/Comparator';
+import { double, float, int, List } from '../../../../customTypings';
+
+// package com.google.zxing.multi.qrcode.detector;
+
+// import com.google.zxing.DecodeHintType;
+// import com.google.zxing.NotFoundException;
+// import com.google.zxing.ResultPoint;
+// import com.google.zxing.ResultPointCallback;
+// import com.google.zxing.common.BitMatrix;
+// import com.google.zxing.qrcode.detector.FinderPattern;
+// import com.google.zxing.qrcode.detector.FinderPatternFinder;
+// import com.google.zxing.qrcode.detector.FinderPatternInfo;
+
+// import java.io.Serializable;
+// import java.util.ArrayList;
+// import java.util.Collections;
+// import java.util.Comparator;
+// import java.util.List;
+// import java.util.Map;
+
+/**
+ * This class attempts to find finder patterns in a QR Code. Finder patterns are the square
+ * markers at three corners of a QR Code.
+ *
+ * This class is thread-safe but not reentrant. Each thread must allocate its own object.
+ *
+ *
In contrast to {@link FinderPatternFinder}, this class will return an array of all possible
+ * QR code locations in the image.
+ *
+ * Use the TRY_HARDER hint to ask for a more thorough detection.
+ *
+ * @author Sean Owen
+ * @author Hannes Erven
+ */
+export default /* public final */ class MultiFinderPatternFinder extends FinderPatternFinder {
+
+ private static /* final */ EMPTY_RESULT_ARRAY: FinderPatternInfo[] = [];
+ private static /* final */ EMPTY_FP_ARRAY: FinderPattern[] = [];
+ private static /* final */ EMPTY_FP_2D_ARRAY: FinderPattern[][] = [[]];
+
+ // TODO MIN_MODULE_COUNT and MAX_MODULE_COUNT would be great hints to ask the user for
+ // since it limits the number of regions to decode
+
+ // max. legal count of modules per QR code edge (177)
+ private static /* final */ MAX_MODULE_COUNT_PER_EDGE: float = 180;
+ // min. legal count per modules per QR code edge (11)
+ private static /* final */ MIN_MODULE_COUNT_PER_EDGE: float = 9;
+
+ /**
+ * More or less arbitrary cutoff point for determining if two finder patterns might belong
+ * to the same code if they differ less than DIFF_MODSIZE_CUTOFF_PERCENT percent in their
+ * estimated modules sizes.
+ */
+ private static /* final */ DIFF_MODSIZE_CUTOFF_PERCENT: float = 0.05;
+
+ /**
+ * More or less arbitrary cutoff point for determining if two finder patterns might belong
+ * to the same code if they differ less than DIFF_MODSIZE_CUTOFF pixels/module in their
+ * estimated modules sizes.
+ */
+ private static /* final */ DIFF_MODSIZE_CUTOFF: float = 0.5;
+
+
+ public constructor(image: BitMatrix, resultPointCallback: ResultPointCallback) {
+ super(image, resultPointCallback);
+ }
+
+ /**
+ * @return the 3 best {@link FinderPattern}s from our list of candidates. The "best" are
+ * those that have been detected at least 2 times, and whose module
+ * size differs from the average among those patterns the least
+ * @throws NotFoundException if 3 such finder patterns do not exist
+ */
+ private selectMultipleBestPatterns(): FinderPattern[][] {
+ const possibleCenters: List = this.getPossibleCenters();
+ const size: int = possibleCenters.length;
+
+ if (size < 3) {
+ // Couldn't find enough finder patterns
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ /*
+ * Begin HE modifications to safely detect multiple codes of equal size
+ */
+ if (size === 3) {
+ return [ possibleCenters ];
+ }
+
+ // Sort by estimated module size to speed up the upcoming checks
+ Collections.sort(possibleCenters, new ModuleSizeComparator());
+
+ /*
+ * Now lets start: build a list of tuples of three finder locations that
+ * - feature similar module sizes
+ * - are placed in a distance so the estimated module count is within the QR specification
+ * - have similar distance between upper left/right and left top/bottom finder patterns
+ * - form a triangle with 90° angle (checked by comparing top right/bottom left distance
+ * with pythagoras)
+ *
+ * Note: we allow each point to be used for more than one code region: this might seem
+ * counterintuitive at first, but the performance penalty is not that big. At this point,
+ * we cannot make a good quality decision whether the three finders actually represent
+ * a QR code, or are just by chance laid out so it looks like there might be a QR code there.
+ * So, if the layout seems right, lets have the decoder try to decode.
+ */
+
+ const results: List = new Array(); // holder for the results
+
+ for (let i1: int = 0; i1 < (size - 2); i1++) {
+ const p1: FinderPattern = possibleCenters[i1];
+ if (p1 == null) {
+ continue;
+ }
+
+ for (let i2: int = i1 + 1; i2 < (size - 1); i2++) {
+ const p2: FinderPattern = possibleCenters[i2];
+ if (p2 == null) {
+ continue;
+ }
+
+ // Compare the expected module sizes; if they are really off, skip
+ const vModSize12: float = (p1.getEstimatedModuleSize() - p2.getEstimatedModuleSize()) /
+ Math.min(p1.getEstimatedModuleSize(), p2.getEstimatedModuleSize());
+ const vModSize12A: float = Math.abs(p1.getEstimatedModuleSize() - p2.getEstimatedModuleSize());
+ if (vModSize12A > MultiFinderPatternFinder.DIFF_MODSIZE_CUTOFF && vModSize12 >= MultiFinderPatternFinder.DIFF_MODSIZE_CUTOFF_PERCENT) {
+ // break, since elements are ordered by the module size deviation there cannot be
+ // any more interesting elements for the given p1.
+ break;
+ }
+
+ for (let i3: int = i2 + 1; i3 < size; i3++) {
+ const p3: FinderPattern = possibleCenters[i3];
+ if (p3 == null) {
+ continue;
+ }
+
+ // Compare the expected module sizes; if they are really off, skip
+ const vModSize23: float = (p2.getEstimatedModuleSize() - p3.getEstimatedModuleSize()) /
+ Math.min(p2.getEstimatedModuleSize(), p3.getEstimatedModuleSize());
+ const vModSize23A: float = Math.abs(p2.getEstimatedModuleSize() - p3.getEstimatedModuleSize());
+ if (vModSize23A > MultiFinderPatternFinder.DIFF_MODSIZE_CUTOFF && vModSize23 >= MultiFinderPatternFinder.DIFF_MODSIZE_CUTOFF_PERCENT) {
+ // break, since elements are ordered by the module size deviation there cannot be
+ // any more interesting elements for the given p1.
+ break;
+ }
+
+ const test: FinderPattern[] = [p1, p2, p3];
+ ResultPoint.orderBestPatterns(test);
+
+ // Calculate the distances: a = topleft-bottomleft, b=topleft-topright, c = diagonal
+ const info: FinderPatternInfo = new FinderPatternInfo(test);
+ const dA: float = ResultPoint.distance(info.getTopLeft(), info.getBottomLeft());
+ const dC: float = ResultPoint.distance(info.getTopRight(), info.getBottomLeft());
+ const dB: float = ResultPoint.distance(info.getTopLeft(), info.getTopRight());
+
+ // Check the sizes
+ const estimatedModuleCount: float = (dA + dB) / (p1.getEstimatedModuleSize() * 2.0);
+ if (estimatedModuleCount > MultiFinderPatternFinder.MAX_MODULE_COUNT_PER_EDGE ||
+ estimatedModuleCount < MultiFinderPatternFinder.MIN_MODULE_COUNT_PER_EDGE) {
+ continue;
+ }
+
+ // Calculate the difference of the edge lengths in percent
+ const vABBC: float = Math.abs((dA - dB) / Math.min(dA, dB));
+ if (vABBC >= 0.1) {
+ continue;
+ }
+
+ // Calculate the diagonal length by assuming a 90° angle at topleft
+ const dCpy: float = Math.sqrt( dA * dA + dB * dB);
+ // Compare to the real distance in %
+ const vPyC: float = Math.abs((dC - dCpy) / Math.min(dC, dCpy));
+
+ if (vPyC >= 0.1) {
+ continue;
+ }
+
+ // All tests passed!
+ results.push(test);
+ }
+ }
+ }
+
+ if (results.length > 0) {
+ return results/* .toArray(MultiFinderPatternFinder.EMPTY_FP_2D_ARRAY) */;
+ }
+
+ // Nothing found!
+ throw NotFoundException.getNotFoundInstance();
+ }
+
+ /**
+ * @throws NotFoundException
+ */
+ public findMulti(hints: Map): FinderPatternInfo[] {
+ const tryHarder: boolean = hints != null && hints.has(DecodeHintType.TRY_HARDER);
+ const image: BitMatrix = this.getImage();
+ const maxI: int = image.getHeight();
+ const maxJ: int = image.getWidth();
+ // We are looking for black/white/black/white/black modules in
+ // 1:1:3:1:1 ratio; this tracks the number of such modules seen so far
+
+ // Let's assume that the maximum version QR Code we support takes up 1/4 the height of the
+ // image, and then account for the center being 3 modules in size. This gives the smallest
+ // number of pixels the center could be, so skip this often. When trying harder, look for all
+ // QR versions regardless of how dense they are.
+ let iSkip: int = Math.trunc((3 * maxI) / (4 * MultiFinderPatternFinder.MAX_MODULES)); // TYPESCRIPTPORT: Java integer divisions always discard decimal chars.
+ if (iSkip < MultiFinderPatternFinder.MIN_SKIP || tryHarder) {
+ iSkip = MultiFinderPatternFinder.MIN_SKIP;
+ }
+
+ const stateCount: Int32Array = Int32Array.from({ length: 5 });
+ for (let i: int = iSkip - 1; i < maxI; i += iSkip) {
+ // Get a row of black/white values
+ this.clearCounts(stateCount);
+ let currentState: int = 0;
+ for (let j: int = 0; j < maxJ; j++) {
+ if (image.get(j, i)) {
+ // Black pixel
+ if ((currentState & 1) === 1) { // Counting white pixels
+ currentState++;
+ }
+ stateCount[currentState]++;
+ } else { // White pixel
+ if ((currentState & 1) === 0) { // Counting black pixels
+ if (currentState === 4) { // A winner?
+ if (MultiFinderPatternFinder.foundPatternCross(stateCount) && this.handlePossibleCenter(stateCount, i, j)) { // Yes
+ // Clear state to start looking again
+ currentState = 0;
+ this.clearCounts(stateCount);
+ } else { // No, shift counts back by two
+ this.shiftCounts2(stateCount);
+ currentState = 3;
+ }
+ } else {
+ stateCount[++currentState]++;
+ }
+ } else { // Counting white pixels
+ stateCount[currentState]++;
+ }
+ }
+ } // for j=...
+
+ if (MultiFinderPatternFinder.foundPatternCross(stateCount)) {
+ this.handlePossibleCenter(stateCount, i, maxJ);
+ }
+ } // for i=iSkip-1 ...
+ const patternInfo: FinderPattern[][] = this.selectMultipleBestPatterns();
+ const result: List = new Array();
+ for (const pattern of patternInfo) {
+ ResultPoint.orderBestPatterns(pattern);
+ result.push(new FinderPatternInfo(pattern));
+ }
+
+ if (result.length === 0) {
+ return MultiFinderPatternFinder.EMPTY_RESULT_ARRAY;
+ } else {
+ return result/* .toArray(MultiFinderPatternFinder.EMPTY_RESULT_ARRAY) */;
+ }
+ }
+
+}
+
+ /**
+ * A comparator that orders FinderPatterns by their estimated module size.
+ */
+ /* private static final */ class ModuleSizeComparator implements Comparator/* , Serializable */ {
+ /** @override */
+ public compare(center1: FinderPattern, center2: FinderPattern): int {
+ const value: float = center2.getEstimatedModuleSize() - center1.getEstimatedModuleSize();
+ return value < 0.0 ? -1 : value > 0.0 ? 1 : 0;
+ }
+ }
diff --git a/src/core/oned/AbstractUPCEANReader.ts b/src/core/oned/AbstractUPCEANReader.ts
index 5704dc0f..271c247d 100644
--- a/src/core/oned/AbstractUPCEANReader.ts
+++ b/src/core/oned/AbstractUPCEANReader.ts
@@ -16,6 +16,7 @@
import BitArray from '../common/BitArray';
import DecodeHintType from '../DecodeHintType';
+import StringBuilder from '../util/StringBuilder';
import Result from '../Result';
import OneDReader from './OneDReader';
@@ -32,210 +33,237 @@ import { int } from '../../customTypings';
* @author alasdair@google.com (Alasdair Mackintosh)
*/
export default abstract class AbstractUPCEANReader extends OneDReader {
- // These two values are critical for determining how permissive the decoding will be.
- // We've arrived at these values through a lot of trial and error. Setting them any higher
- // lets false positives creep in quickly.
- private static MAX_AVG_VARIANCE = 0.48;
- private static MAX_INDIVIDUAL_VARIANCE = 0.7;
-
- /**
- * Start/end guard pattern.
- */
- public static START_END_PATTERN: Int32Array = Int32Array.from([1, 1, 1]);
-
- /**
- * Pattern marking the middle of a UPC/EAN pattern, separating the two halves.
- */
- public static MIDDLE_PATTERN: Int32Array = Int32Array.from([1, 1, 1, 1, 1]);
- /**
- * end guard pattern.
- */
- public static END_PATTERN: Int32Array = Int32Array.from([1, 1, 1, 1, 1, 1]);
- /**
- * "Odd", or "L" patterns used to encode UPC/EAN digits.
- */
- public static L_PATTERNS: Int32Array[] = [
- Int32Array.from([3, 2, 1, 1]), // 0
- Int32Array.from([2, 2, 2, 1]), // 1
- Int32Array.from([2, 1, 2, 2]), // 2
- Int32Array.from([1, 4, 1, 1]), // 3
- Int32Array.from([1, 1, 3, 2]), // 4
- Int32Array.from([1, 2, 3, 1]), // 5
- Int32Array.from([1, 1, 1, 4]), // 6
- Int32Array.from([1, 3, 1, 2]), // 7
- Int32Array.from([1, 2, 1, 3]), // 8
- Int32Array.from([3, 1, 1, 2]), // 9
- ];
-
- /**
- * As above but also including the "even", or "G" patterns used to encode UPC/EAN digits.
- */
- public static L_AND_G_PATTERNS: Int32Array[];
-
- protected decodeRowStringBuffer = '';
- // private final UPCEANExtensionSupport extensionReader;
- // private final EANManufacturerOrgSupport eanManSupport;
-
-
- /*
- protected UPCEANReader() {
- decodeRowStringBuffer = new StringBuilder(20);
- extensionReader = new UPCEANExtensionSupport();
- eanManSupport = new EANManufacturerOrgSupport();
- }
- */
-
- static findStartGuardPattern(row: BitArray): Int32Array {
- let foundStart = false;
- let startRange: Int32Array;
- let nextStart = 0;
- let counters = Int32Array.from([0, 0, 0]);
- while (!foundStart) {
- counters = Int32Array.from([0, 0, 0]);
- startRange = AbstractUPCEANReader.findGuardPattern(row, nextStart, false, this.START_END_PATTERN, counters);
- let start = startRange[0];
- nextStart = startRange[1];
- let quietStart = start - (nextStart - start);
- if (quietStart >= 0) {
- foundStart = row.isRange(quietStart, start, false);
- }
- }
- return startRange;
- }
+ // These two values are critical for determining how permissive the decoding will be.
+ // We've arrived at these values through a lot of trial and error. Setting them any higher
+ // lets false positives creep in quickly.
+ private static MAX_AVG_VARIANCE = 0.48;
+ private static MAX_INDIVIDUAL_VARIANCE = 0.7;
- public abstract decodeRow(rowNumber: number, row: BitArray, hints?: Map): Result;
+ /**
+ * Start/end guard pattern.
+ */
+ public static START_END_PATTERN: Int32Array = Int32Array.from([1, 1, 1]);
- static checkChecksum(s: string): boolean {
- return AbstractUPCEANReader.checkStandardUPCEANChecksum(s);
- }
+ /**
+ * Pattern marking the middle of a UPC/EAN pattern, separating the two halves.
+ */
+ public static MIDDLE_PATTERN: Int32Array = Int32Array.from([1, 1, 1, 1, 1]);
+ /**
+ * end guard pattern.
+ */
+ public static END_PATTERN: Int32Array = Int32Array.from([1, 1, 1, 1, 1, 1]);
+ /**
+ * "Odd", or "L" patterns used to encode UPC/EAN digits.
+ */
+ public static L_PATTERNS: Int32Array[] = [
+ Int32Array.from([3, 2, 1, 1]), // 0
+ Int32Array.from([2, 2, 2, 1]), // 1
+ Int32Array.from([2, 1, 2, 2]), // 2
+ Int32Array.from([1, 4, 1, 1]), // 3
+ Int32Array.from([1, 1, 3, 2]), // 4
+ Int32Array.from([1, 2, 3, 1]), // 5
+ Int32Array.from([1, 1, 1, 4]), // 6
+ Int32Array.from([1, 3, 1, 2]), // 7
+ Int32Array.from([1, 2, 1, 3]), // 8
+ Int32Array.from([3, 1, 1, 2]), // 9
+ ];
- static checkStandardUPCEANChecksum(s: string): boolean {
- let length = s.length;
- if (length === 0) return false;
+ /**
+ * As above but also including the "even", or "G" patterns used to encode UPC/EAN digits.
+ */
+ public static L_AND_G_PATTERNS: Int32Array[];
- let check = parseInt(s.charAt(length - 1), 10);
- return AbstractUPCEANReader.getStandardUPCEANChecksum(s.substring(0, length - 1)) === check;
- }
+ protected decodeRowStringBuffer = new StringBuilder();
+ // private final UPCEANExtensionSupport extensionReader;
+ // private final EANManufacturerOrgSupport eanManSupport;
- static getStandardUPCEANChecksum(s: string): number {
- let length = s.length;
- let sum = 0;
- for (let i = length - 1; i >= 0; i -= 2) {
- let digit = s.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
- if (digit < 0 || digit > 9) {
- throw new FormatException();
- }
- sum += digit;
- }
- sum *= 3;
- for (let i = length - 2; i >= 0; i -= 2) {
- let digit = s.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
- if (digit < 0 || digit > 9) {
- throw new FormatException();
- }
- sum += digit;
- }
- return (1000 - sum) % 10;
- }
- static decodeEnd(row: BitArray, endStart: number): Int32Array {
- return AbstractUPCEANReader.findGuardPattern(row, endStart, false, AbstractUPCEANReader.START_END_PATTERN, new Int32Array(AbstractUPCEANReader.START_END_PATTERN.length).fill(0));
- }
+ /*
+ protected UPCEANReader() {
+ decodeRowStringBuffer = new StringBuilder(20);
+ extensionReader = new UPCEANExtensionSupport();
+ eanManSupport = new EANManufacturerOrgSupport();
+ }
+ */
- /**
- * @throws NotFoundException
- */
- static findGuardPatternWithoutCounters(
- row: BitArray,
- rowOffset: int,
- whiteFirst: boolean,
- pattern: Int32Array,
- ): Int32Array {
- return this.findGuardPattern(row, rowOffset, whiteFirst, pattern, new Int32Array(pattern.length));
+ static findStartGuardPattern(row: BitArray): Int32Array {
+ let foundStart = false;
+ let startRange: Int32Array;
+ let nextStart = 0;
+ let counters: Int32Array;
+ while (!foundStart) {
+ counters = new Int32Array(3);
+ startRange = AbstractUPCEANReader.findGuardPattern(row, nextStart, false, this.START_END_PATTERN, counters);
+ let start = startRange[0];
+ nextStart = startRange[1];
+ let quietStart = start - (nextStart - start);
+ if (quietStart >= 0) {
+ foundStart = row.isRange(quietStart, start, false);
+ }
}
+ return startRange;
+ }
- /**
- * @param row row of black/white values to search
- * @param rowOffset position to start search
- * @param whiteFirst if true, indicates that the pattern specifies white/black/white/...
- * pixel counts, otherwise, it is interpreted as black/white/black/...
- * @param pattern pattern of counts of number of black and white pixels that are being
- * searched for as a pattern
- * @param counters array of counters, as long as pattern, to re-use
- * @return start/end horizontal offset of guard pattern, as an array of two ints
- * @throws NotFoundException if pattern is not found
- */
- static findGuardPattern(row: BitArray, rowOffset: number, whiteFirst: boolean, pattern: Int32Array, counters: Int32Array): Int32Array {
- let width = row.getSize();
- rowOffset = whiteFirst ? row.getNextUnset(rowOffset) : row.getNextSet(rowOffset);
- let counterPosition = 0;
- let patternStart = rowOffset;
- let patternLength = pattern.length;
- let isWhite = whiteFirst;
- for (let x = rowOffset; x < width; x++) {
- if (row.get(x) !== isWhite) {
- counters[counterPosition]++;
- } else {
- if (counterPosition === patternLength - 1) {
- if (OneDReader.patternMatchVariance(counters, pattern, AbstractUPCEANReader.MAX_INDIVIDUAL_VARIANCE) < AbstractUPCEANReader.MAX_AVG_VARIANCE) {
- return Int32Array.from([patternStart, x]);
- }
- patternStart += counters[0] + counters[1];
-
- let slice = counters.slice(2, counters.length - 1);
- for (let i = 0; i < counterPosition - 1; i++) {
- counters[i] = slice[i];
- }
-
- counters[counterPosition - 1] = 0;
- counters[counterPosition] = 0;
- counterPosition--;
- } else {
- counterPosition++;
- }
- counters[counterPosition] = 1;
- isWhite = !isWhite;
- }
- }
- throw new NotFoundException();
+ /**
+ * Attempts to decode a one-dimensional barcode format given a single row of
+ * an image.
+ *
+ * @param rowNumber row number from top of the row
+ * @param row the black/white pixel data of the row
+ * @param hints hints that influence decoding
+ * @return containing encoded string and start/end of barcode
+ * @throws {@link NotFoundException} if no potential barcode is found
+ * @throws {@link ChecksumException} if a potential barcode is found but does not pass its checksum
+ * @throws {@link FormatException} if a potential barcode is found but format is invalid
+ */
+ public abstract decodeRow(rowNumber: number, row: BitArray, hints?: Map): Result;
+ /**
+ * Attempts to decode a one-dimensional barcode format given a single row of
+ * an image, but allows caller to inform method about where the UPC/EAN start pattern is found.
+ * This allows this to be computed once and reused across many implementations.
+ *
+ * @param rowNumber row number from top of the row
+ * @param row the black/white pixel data of the row
+ * @param startGuardRange start/end column where the opening start pattern is found
+ * @param hints hints that influence decoding
+ * @return encapsulating the result of decoding a barcode in the row
+ * @throws {@link NotFoundException} if no potential barcode is found
+ * @throws {@link ChecksumException} if a potential barcode is found but does not pass its checksum
+ * @throws {@link FormatException} if a potential barcode is found but format is invalid
+ */
+ public abstract decodeRow(rowNumber: number, row: BitArray, startGuardRange: Int32Array, hints?: Map): Result;
+
+ static checkChecksum(s: string): boolean {
+ return AbstractUPCEANReader.checkStandardUPCEANChecksum(s);
+ }
+
+ static checkStandardUPCEANChecksum(s: string): boolean {
+ let length = s.length;
+ if (length === 0) return false;
+
+ let check = parseInt(s.charAt(length - 1), 10);
+ return AbstractUPCEANReader.getStandardUPCEANChecksum(s.substring(0, length - 1)) === check;
+ }
+
+ static getStandardUPCEANChecksum(s: string): number {
+ let length = s.length;
+ let sum = 0;
+ for (let i = length - 1; i >= 0; i -= 2) {
+ let digit = s.charCodeAt(i) - '0'.charCodeAt(0);
+ if (digit < 0 || digit > 9) {
+ throw new FormatException();
+ }
+ sum += digit;
+ }
+ sum *= 3;
+ for (let i = length - 2; i >= 0; i -= 2) {
+ let digit = s.charCodeAt(i) - '0'.charCodeAt(0);
+ if (digit < 0 || digit > 9) {
+ throw new FormatException();
+ }
+ sum += digit;
}
+ return (1000 - sum) % 10;
+ }
- static decodeDigit(row: BitArray, counters: Int32Array, rowOffset: int, patterns: Int32Array[]) {
- this.recordPattern(row, rowOffset, counters);
- let bestVariance = this.MAX_AVG_VARIANCE;
- let bestMatch = -1;
- let max = patterns.length;
- for (let i = 0; i < max; i++) {
- let pattern = patterns[i];
- let variance = OneDReader.patternMatchVariance(counters, pattern, AbstractUPCEANReader.MAX_INDIVIDUAL_VARIANCE);
- if (variance < bestVariance) {
- bestVariance = variance;
- bestMatch = i;
- }
- }
- if (bestMatch >= 0) {
- return bestMatch;
+ protected decodeEnd(row: BitArray, endStart: number): Int32Array {
+ return AbstractUPCEANReader.findGuardPattern(row, endStart, false, AbstractUPCEANReader.START_END_PATTERN);
+ }
+
+ /**
+ * @param row row of black/white values to search
+ * @param rowOffset position to start search
+ * @param whiteFirst if true, indicates that the pattern specifies white/black/white/...
+ * pixel counts, otherwise, it is interpreted as black/white/black/...
+ * @param pattern pattern of counts of number of black and white pixels that are being
+ * searched for as a pattern
+ * @return start/end horizontal offset of guard pattern, as an array of two ints
+ * @throws {@link NotFoundException} if pattern is not found
+ */
+ static findGuardPattern(row: BitArray, rowOffset: int, whiteFirst: boolean, pattern: Int32Array): Int32Array;
+ /**
+ * @param row row of black/white values to search
+ * @param rowOffset position to start search
+ * @param whiteFirst if true, indicates that the pattern specifies white/black/white/...
+ * pixel counts, otherwise, it is interpreted as black/white/black/...
+ * @param pattern pattern of counts of number of black and white pixels that are being
+ * searched for as a pattern
+ * @param counters array of counters, as long as pattern, to re-use
+ * @return start/end horizontal offset of guard pattern, as an array of two ints
+ * @throws {@link NotFoundException} if pattern is not found
+ */
+ static findGuardPattern(row: BitArray, rowOffset: number, whiteFirst: boolean, pattern: Int32Array, counters: Int32Array): Int32Array;
+ static findGuardPattern(row: BitArray, rowOffset: number, whiteFirst: boolean, pattern: Int32Array, counters?: Int32Array): Int32Array {
+ if (typeof counters === 'undefined') counters = new Int32Array(pattern.length);
+ return this.findGuardPatternImpl(row, rowOffset, whiteFirst, pattern, counters);
+ }
+
+ static findGuardPatternImpl(row: BitArray, rowOffset: number, whiteFirst: boolean, pattern: Int32Array, counters: Int32Array): Int32Array {
+ let width = row.getSize();
+ rowOffset = whiteFirst ? row.getNextUnset(rowOffset) : row.getNextSet(rowOffset);
+ let counterPosition = 0;
+ let patternStart = rowOffset;
+ let patternLength = pattern.length;
+ let isWhite = whiteFirst;
+ for (let x = rowOffset; x < width; x++) {
+ if (row.get(x) !== isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (counterPosition === patternLength - 1) {
+ if (OneDReader.patternMatchVariance(counters, pattern, AbstractUPCEANReader.MAX_INDIVIDUAL_VARIANCE) < AbstractUPCEANReader.MAX_AVG_VARIANCE) {
+ return new Int32Array([patternStart, x]);
+ }
+ patternStart += counters[0] + counters[1];
+ counters.copyWithin(0, 2, 2 + counterPosition - 1);
+ counters[counterPosition - 1] = 0;
+ counters[counterPosition] = 0;
+ counterPosition--;
} else {
- throw new NotFoundException();
+ counterPosition++;
}
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+ throw new NotFoundException();
+ }
+
+ static decodeDigit(row: BitArray, counters: Int32Array, rowOffset: int, patterns: Int32Array[]) {
+ this.recordPattern(row, rowOffset, counters);
+ let bestVariance = this.MAX_AVG_VARIANCE;
+ let bestMatch = -1;
+ let max = patterns.length;
+ for (let i = 0; i < max; i++) {
+ let pattern = patterns[i];
+ let variance = OneDReader.patternMatchVariance(counters, pattern, AbstractUPCEANReader.MAX_INDIVIDUAL_VARIANCE);
+ if (variance < bestVariance) {
+ bestVariance = variance;
+ bestMatch = i;
+ }
+ }
+ if (bestMatch >= 0) {
+ return bestMatch;
+ } else {
+ throw new NotFoundException();
}
+ }
- /**
- * Get the format of this decoder.
- *
- * @return The 1D format.
- */
- public abstract getBarcodeFormat();
-
- /**
- * Subclasses override this to decode the portion of a barcode between the start
- * and end guard patterns.
- *
- * @param row row of black/white values to search
- * @param startRange start/end offset of start guard pattern
- * @param resultString {@link StringBuilder} to append decoded chars to
- * @return horizontal offset of first pixel after the "middle" that was decoded
- * @throws NotFoundException if decoding could not complete successfully
- */
- public abstract decodeMiddle(row: BitArray, startRange: Int32Array, resultString: /*StringBuilder*/string);
+ /**
+ * Get the format of this decoder.
+ *
+ * @return The 1D format.
+ */
+ public abstract getBarcodeFormat();
+
+ /**
+ * Subclasses override this to decode the portion of a barcode between the start
+ * and end guard patterns.
+ *
+ * @param row row of black/white values to search
+ * @param startRange start/end offset of start guard pattern
+ * @param resultString to append decoded chars to
+ * @return horizontal offset of first pixel after the "middle" that was decoded
+ * @throws NotFoundException if decoding could not complete successfully
+ */
+ public abstract decodeMiddle(row: BitArray, startRange: Int32Array, resultString: StringBuilder);
}
diff --git a/src/core/oned/Code128Reader.ts b/src/core/oned/Code128Reader.ts
index 72c5bb68..9e483329 100644
--- a/src/core/oned/Code128Reader.ts
+++ b/src/core/oned/Code128Reader.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.oned {*/
+/* namespace com.google.zxing.oned { */
import BarcodeFormat from '../BarcodeFormat';
import ChecksumException from '../ChecksumException';
@@ -37,115 +37,115 @@ import OneDReader from './OneDReader';
*/
export default class Code128Reader extends OneDReader {
- private static CODE_PATTERNS: Int32Array[] = [
- Int32Array.from([2, 1, 2, 2, 2, 2]),
- Int32Array.from([2, 2, 2, 1, 2, 2]),
- Int32Array.from([2, 2, 2, 2, 2, 1]),
- Int32Array.from([1, 2, 1, 2, 2, 3]),
- Int32Array.from([1, 2, 1, 3, 2, 2]),
- Int32Array.from([1, 3, 1, 2, 2, 2]),
- Int32Array.from([1, 2, 2, 2, 1, 3]),
- Int32Array.from([1, 2, 2, 3, 1, 2]),
- Int32Array.from([1, 3, 2, 2, 1, 2]),
- Int32Array.from([2, 2, 1, 2, 1, 3]),
- Int32Array.from([2, 2, 1, 3, 1, 2]),
- Int32Array.from([2, 3, 1, 2, 1, 2]),
- Int32Array.from([1, 1, 2, 2, 3, 2]),
- Int32Array.from([1, 2, 2, 1, 3, 2]),
- Int32Array.from([1, 2, 2, 2, 3, 1]),
- Int32Array.from([1, 1, 3, 2, 2, 2]),
- Int32Array.from([1, 2, 3, 1, 2, 2]),
- Int32Array.from([1, 2, 3, 2, 2, 1]),
- Int32Array.from([2, 2, 3, 2, 1, 1]),
- Int32Array.from([2, 2, 1, 1, 3, 2]),
- Int32Array.from([2, 2, 1, 2, 3, 1]),
- Int32Array.from([2, 1, 3, 2, 1, 2]),
- Int32Array.from([2, 2, 3, 1, 1, 2]),
- Int32Array.from([3, 1, 2, 1, 3, 1]),
- Int32Array.from([3, 1, 1, 2, 2, 2]),
- Int32Array.from([3, 2, 1, 1, 2, 2]),
- Int32Array.from([3, 2, 1, 2, 2, 1]),
- Int32Array.from([3, 1, 2, 2, 1, 2]),
- Int32Array.from([3, 2, 2, 1, 1, 2]),
- Int32Array.from([3, 2, 2, 2, 1, 1]),
- Int32Array.from([2, 1, 2, 1, 2, 3]),
- Int32Array.from([2, 1, 2, 3, 2, 1]),
- Int32Array.from([2, 3, 2, 1, 2, 1]),
- Int32Array.from([1, 1, 1, 3, 2, 3]),
- Int32Array.from([1, 3, 1, 1, 2, 3]),
- Int32Array.from([1, 3, 1, 3, 2, 1]),
- Int32Array.from([1, 1, 2, 3, 1, 3]),
- Int32Array.from([1, 3, 2, 1, 1, 3]),
- Int32Array.from([1, 3, 2, 3, 1, 1]),
- Int32Array.from([2, 1, 1, 3, 1, 3]),
- Int32Array.from([2, 3, 1, 1, 1, 3]),
- Int32Array.from([2, 3, 1, 3, 1, 1]),
- Int32Array.from([1, 1, 2, 1, 3, 3]),
- Int32Array.from([1, 1, 2, 3, 3, 1]),
- Int32Array.from([1, 3, 2, 1, 3, 1]),
- Int32Array.from([1, 1, 3, 1, 2, 3]),
- Int32Array.from([1, 1, 3, 3, 2, 1]),
- Int32Array.from([1, 3, 3, 1, 2, 1]),
- Int32Array.from([3, 1, 3, 1, 2, 1]),
- Int32Array.from([2, 1, 1, 3, 3, 1]),
- Int32Array.from([2, 3, 1, 1, 3, 1]),
- Int32Array.from([2, 1, 3, 1, 1, 3]),
- Int32Array.from([2, 1, 3, 3, 1, 1]),
- Int32Array.from([2, 1, 3, 1, 3, 1]),
- Int32Array.from([3, 1, 1, 1, 2, 3]),
- Int32Array.from([3, 1, 1, 3, 2, 1]),
- Int32Array.from([3, 3, 1, 1, 2, 1]),
- Int32Array.from([3, 1, 2, 1, 1, 3]),
- Int32Array.from([3, 1, 2, 3, 1, 1]),
- Int32Array.from([3, 3, 2, 1, 1, 1]),
- Int32Array.from([3, 1, 4, 1, 1, 1]),
- Int32Array.from([2, 2, 1, 4, 1, 1]),
- Int32Array.from([4, 3, 1, 1, 1, 1]),
- Int32Array.from([1, 1, 1, 2, 2, 4]),
- Int32Array.from([1, 1, 1, 4, 2, 2]),
- Int32Array.from([1, 2, 1, 1, 2, 4]),
- Int32Array.from([1, 2, 1, 4, 2, 1]),
- Int32Array.from([1, 4, 1, 1, 2, 2]),
- Int32Array.from([1, 4, 1, 2, 2, 1]),
- Int32Array.from([1, 1, 2, 2, 1, 4]),
- Int32Array.from([1, 1, 2, 4, 1, 2]),
- Int32Array.from([1, 2, 2, 1, 1, 4]),
- Int32Array.from([1, 2, 2, 4, 1, 1]),
- Int32Array.from([1, 4, 2, 1, 1, 2]),
- Int32Array.from([1, 4, 2, 2, 1, 1]),
- Int32Array.from([2, 4, 1, 2, 1, 1]),
- Int32Array.from([2, 2, 1, 1, 1, 4]),
- Int32Array.from([4, 1, 3, 1, 1, 1]),
- Int32Array.from([2, 4, 1, 1, 1, 2]),
- Int32Array.from([1, 3, 4, 1, 1, 1]),
- Int32Array.from([1, 1, 1, 2, 4, 2]),
- Int32Array.from([1, 2, 1, 1, 4, 2]),
- Int32Array.from([1, 2, 1, 2, 4, 1]),
- Int32Array.from([1, 1, 4, 2, 1, 2]),
- Int32Array.from([1, 2, 4, 1, 1, 2]),
- Int32Array.from([1, 2, 4, 2, 1, 1]),
- Int32Array.from([4, 1, 1, 2, 1, 2]),
- Int32Array.from([4, 2, 1, 1, 1, 2]),
- Int32Array.from([4, 2, 1, 2, 1, 1]),
- Int32Array.from([2, 1, 2, 1, 4, 1]),
- Int32Array.from([2, 1, 4, 1, 2, 1]),
- Int32Array.from([4, 1, 2, 1, 2, 1]),
- Int32Array.from([1, 1, 1, 1, 4, 3]),
- Int32Array.from([1, 1, 1, 3, 4, 1]),
- Int32Array.from([1, 3, 1, 1, 4, 1]),
- Int32Array.from([1, 1, 4, 1, 1, 3]),
- Int32Array.from([1, 1, 4, 3, 1, 1]),
- Int32Array.from([4, 1, 1, 1, 1, 3]),
- Int32Array.from([4, 1, 1, 3, 1, 1]),
- Int32Array.from([1, 1, 3, 1, 4, 1]),
- Int32Array.from([1, 1, 4, 1, 3, 1]),
- Int32Array.from([3, 1, 1, 1, 4, 1]),
- Int32Array.from([4, 1, 1, 1, 3, 1]),
- Int32Array.from([2, 1, 1, 4, 1, 2]),
- Int32Array.from([2, 1, 1, 2, 1, 4]),
- Int32Array.from([2, 1, 1, 2, 3, 2]),
- Int32Array.from([2, 3, 3, 1, 1, 1, 2]),
- ];
+ private static CODE_PATTERNS: Int32Array[] = [
+ Int32Array.from([2, 1, 2, 2, 2, 2]),
+ Int32Array.from([2, 2, 2, 1, 2, 2]),
+ Int32Array.from([2, 2, 2, 2, 2, 1]),
+ Int32Array.from([1, 2, 1, 2, 2, 3]),
+ Int32Array.from([1, 2, 1, 3, 2, 2]),
+ Int32Array.from([1, 3, 1, 2, 2, 2]),
+ Int32Array.from([1, 2, 2, 2, 1, 3]),
+ Int32Array.from([1, 2, 2, 3, 1, 2]),
+ Int32Array.from([1, 3, 2, 2, 1, 2]),
+ Int32Array.from([2, 2, 1, 2, 1, 3]),
+ Int32Array.from([2, 2, 1, 3, 1, 2]),
+ Int32Array.from([2, 3, 1, 2, 1, 2]),
+ Int32Array.from([1, 1, 2, 2, 3, 2]),
+ Int32Array.from([1, 2, 2, 1, 3, 2]),
+ Int32Array.from([1, 2, 2, 2, 3, 1]),
+ Int32Array.from([1, 1, 3, 2, 2, 2]),
+ Int32Array.from([1, 2, 3, 1, 2, 2]),
+ Int32Array.from([1, 2, 3, 2, 2, 1]),
+ Int32Array.from([2, 2, 3, 2, 1, 1]),
+ Int32Array.from([2, 2, 1, 1, 3, 2]),
+ Int32Array.from([2, 2, 1, 2, 3, 1]),
+ Int32Array.from([2, 1, 3, 2, 1, 2]),
+ Int32Array.from([2, 2, 3, 1, 1, 2]),
+ Int32Array.from([3, 1, 2, 1, 3, 1]),
+ Int32Array.from([3, 1, 1, 2, 2, 2]),
+ Int32Array.from([3, 2, 1, 1, 2, 2]),
+ Int32Array.from([3, 2, 1, 2, 2, 1]),
+ Int32Array.from([3, 1, 2, 2, 1, 2]),
+ Int32Array.from([3, 2, 2, 1, 1, 2]),
+ Int32Array.from([3, 2, 2, 2, 1, 1]),
+ Int32Array.from([2, 1, 2, 1, 2, 3]),
+ Int32Array.from([2, 1, 2, 3, 2, 1]),
+ Int32Array.from([2, 3, 2, 1, 2, 1]),
+ Int32Array.from([1, 1, 1, 3, 2, 3]),
+ Int32Array.from([1, 3, 1, 1, 2, 3]),
+ Int32Array.from([1, 3, 1, 3, 2, 1]),
+ Int32Array.from([1, 1, 2, 3, 1, 3]),
+ Int32Array.from([1, 3, 2, 1, 1, 3]),
+ Int32Array.from([1, 3, 2, 3, 1, 1]),
+ Int32Array.from([2, 1, 1, 3, 1, 3]),
+ Int32Array.from([2, 3, 1, 1, 1, 3]),
+ Int32Array.from([2, 3, 1, 3, 1, 1]),
+ Int32Array.from([1, 1, 2, 1, 3, 3]),
+ Int32Array.from([1, 1, 2, 3, 3, 1]),
+ Int32Array.from([1, 3, 2, 1, 3, 1]),
+ Int32Array.from([1, 1, 3, 1, 2, 3]),
+ Int32Array.from([1, 1, 3, 3, 2, 1]),
+ Int32Array.from([1, 3, 3, 1, 2, 1]),
+ Int32Array.from([3, 1, 3, 1, 2, 1]),
+ Int32Array.from([2, 1, 1, 3, 3, 1]),
+ Int32Array.from([2, 3, 1, 1, 3, 1]),
+ Int32Array.from([2, 1, 3, 1, 1, 3]),
+ Int32Array.from([2, 1, 3, 3, 1, 1]),
+ Int32Array.from([2, 1, 3, 1, 3, 1]),
+ Int32Array.from([3, 1, 1, 1, 2, 3]),
+ Int32Array.from([3, 1, 1, 3, 2, 1]),
+ Int32Array.from([3, 3, 1, 1, 2, 1]),
+ Int32Array.from([3, 1, 2, 1, 1, 3]),
+ Int32Array.from([3, 1, 2, 3, 1, 1]),
+ Int32Array.from([3, 3, 2, 1, 1, 1]),
+ Int32Array.from([3, 1, 4, 1, 1, 1]),
+ Int32Array.from([2, 2, 1, 4, 1, 1]),
+ Int32Array.from([4, 3, 1, 1, 1, 1]),
+ Int32Array.from([1, 1, 1, 2, 2, 4]),
+ Int32Array.from([1, 1, 1, 4, 2, 2]),
+ Int32Array.from([1, 2, 1, 1, 2, 4]),
+ Int32Array.from([1, 2, 1, 4, 2, 1]),
+ Int32Array.from([1, 4, 1, 1, 2, 2]),
+ Int32Array.from([1, 4, 1, 2, 2, 1]),
+ Int32Array.from([1, 1, 2, 2, 1, 4]),
+ Int32Array.from([1, 1, 2, 4, 1, 2]),
+ Int32Array.from([1, 2, 2, 1, 1, 4]),
+ Int32Array.from([1, 2, 2, 4, 1, 1]),
+ Int32Array.from([1, 4, 2, 1, 1, 2]),
+ Int32Array.from([1, 4, 2, 2, 1, 1]),
+ Int32Array.from([2, 4, 1, 2, 1, 1]),
+ Int32Array.from([2, 2, 1, 1, 1, 4]),
+ Int32Array.from([4, 1, 3, 1, 1, 1]),
+ Int32Array.from([2, 4, 1, 1, 1, 2]),
+ Int32Array.from([1, 3, 4, 1, 1, 1]),
+ Int32Array.from([1, 1, 1, 2, 4, 2]),
+ Int32Array.from([1, 2, 1, 1, 4, 2]),
+ Int32Array.from([1, 2, 1, 2, 4, 1]),
+ Int32Array.from([1, 1, 4, 2, 1, 2]),
+ Int32Array.from([1, 2, 4, 1, 1, 2]),
+ Int32Array.from([1, 2, 4, 2, 1, 1]),
+ Int32Array.from([4, 1, 1, 2, 1, 2]),
+ Int32Array.from([4, 2, 1, 1, 1, 2]),
+ Int32Array.from([4, 2, 1, 2, 1, 1]),
+ Int32Array.from([2, 1, 2, 1, 4, 1]),
+ Int32Array.from([2, 1, 4, 1, 2, 1]),
+ Int32Array.from([4, 1, 2, 1, 2, 1]),
+ Int32Array.from([1, 1, 1, 1, 4, 3]),
+ Int32Array.from([1, 1, 1, 3, 4, 1]),
+ Int32Array.from([1, 3, 1, 1, 4, 1]),
+ Int32Array.from([1, 1, 4, 1, 1, 3]),
+ Int32Array.from([1, 1, 4, 3, 1, 1]),
+ Int32Array.from([4, 1, 1, 1, 1, 3]),
+ Int32Array.from([4, 1, 1, 3, 1, 1]),
+ Int32Array.from([1, 1, 3, 1, 4, 1]),
+ Int32Array.from([1, 1, 4, 1, 3, 1]),
+ Int32Array.from([3, 1, 1, 1, 4, 1]),
+ Int32Array.from([4, 1, 1, 1, 3, 1]),
+ Int32Array.from([2, 1, 1, 4, 1, 2]),
+ Int32Array.from([2, 1, 1, 2, 1, 4]),
+ Int32Array.from([2, 1, 1, 2, 3, 2]),
+ Int32Array.from([2, 3, 3, 1, 1, 1, 2]),
+ ];
private static MAX_AVG_VARIANCE = 0.25;
private static MAX_INDIVIDUAL_VARIANCE = 0.7;
@@ -171,11 +171,11 @@ export default class Code128Reader extends OneDReader {
const width = row.getSize();
const rowOffset = row.getNextSet(0);
- let counterPosition = 0;
- let counters = Int32Array.from([0, 0, 0, 0, 0, 0]);
- let patternStart = rowOffset;
- let isWhite = false;
- const patternLength = 6;
+ let counterPosition = 0;
+ let counters = Int32Array.from([0, 0, 0, 0, 0, 0]);
+ let patternStart = rowOffset;
+ let isWhite = false;
+ const patternLength = 6;
for (let i = rowOffset; i < width; i++) {
if (row.get(i) !== isWhite) {
diff --git a/src/core/oned/Code39Reader.ts b/src/core/oned/Code39Reader.ts
index 4a2c91af..d57aff13 100644
--- a/src/core/oned/Code39Reader.ts
+++ b/src/core/oned/Code39Reader.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.oned {*/
+/* namespace com.google.zxing.oned { */
import BarcodeFormat from '../BarcodeFormat';
import BitArray from '../common/BitArray';
@@ -40,13 +40,13 @@ export default class Code39Reader extends OneDReader {
* These represent the encodings of characters, as patterns of wide and narrow bars.
* The 9 least-significant bits of each int correspond to the pattern of wide and narrow,
* with 1s representing "wide" and 0s representing narrow.
- */
+ */
private static readonly CHARACTER_ENCODINGS: number[] = [
- 0x034, 0x121, 0x061, 0x160, 0x031, 0x130, 0x070, 0x025, 0x124, 0x064, // 0-9
- 0x109, 0x049, 0x148, 0x019, 0x118, 0x058, 0x00D, 0x10C, 0x04C, 0x01C, // A-J
- 0x103, 0x043, 0x142, 0x013, 0x112, 0x052, 0x007, 0x106, 0x046, 0x016, // K-T
- 0x181, 0x0C1, 0x1C0, 0x091, 0x190, 0x0D0, 0x085, 0x184, 0x0C4, 0x0A8, // U-$
- 0x0A2, 0x08A, 0x02A // /-%
+ 0x034, 0x121, 0x061, 0x160, 0x031, 0x130, 0x070, 0x025, 0x124, 0x064, // 0-9
+ 0x109, 0x049, 0x148, 0x019, 0x118, 0x058, 0x00D, 0x10C, 0x04C, 0x01C, // A-J
+ 0x103, 0x043, 0x142, 0x013, 0x112, 0x052, 0x007, 0x106, 0x046, 0x016, // K-T
+ 0x181, 0x0C1, 0x1C0, 0x091, 0x190, 0x0D0, 0x085, 0x184, 0x0C4, 0x0A8, // U-$
+ 0x0A2, 0x08A, 0x02A // /-%
];
private static readonly ASTERISK_ENCODING = 0x094;
@@ -59,7 +59,7 @@ export default class Code39Reader extends OneDReader {
/**
* Creates a reader that assumes all encoded data is data, and does not treat the final
* character as a check digit. It will not decoded "extended Code 39" sequences.
- */
+ */
// public Code39Reader() {
// this(false);
// }
@@ -70,7 +70,7 @@ export default class Code39Reader extends OneDReader {
*
* @param usingCheckDigit if true, treat the last data character as a check digit, not
* data, and verify that the checksum passes.
- */
+ */
// public Code39Reader(boolean usingCheckDigit) {
// this(usingCheckDigit, false);
// }
@@ -84,7 +84,7 @@ export default class Code39Reader extends OneDReader {
* data, and verify that the checksum passes.
* @param extendedMode if true, will attempt to decode extended Code 39 sequences in the
* text.
- */
+ */
public constructor(usingCheckDigit: boolean = false, extendedMode: boolean = false) {
super();
this.usingCheckDigit = usingCheckDigit;
@@ -186,7 +186,7 @@ export default class Code39Reader extends OneDReader {
if (counterPosition === patternLength - 1) {
// Look for whitespace before start pattern, >= 50% of width of start pattern
if (this.toNarrowWidePattern(counters) === Code39Reader.ASTERISK_ENCODING &&
- row.isRange(Math.max(0, patternStart - Math.floor((i - patternStart) / 2)), patternStart, false)) {
+ row.isRange(Math.max(0, patternStart - Math.floor((i - patternStart) / 2)), patternStart, false)) {
return [patternStart, i];
}
patternStart += counters[0] + counters[1];
diff --git a/src/core/oned/EAN13Reader.ts b/src/core/oned/EAN13Reader.ts
index 6412285e..dbb748eb 100644
--- a/src/core/oned/EAN13Reader.ts
+++ b/src/core/oned/EAN13Reader.ts
@@ -16,6 +16,7 @@
import BarcodeFormat from '../BarcodeFormat';
import BitArray from '../common/BitArray';
+import StringBuilder from '../util/StringBuilder';
import UPCEANReader from './UPCEANReader';
import NotFoundException from '../NotFoundException';
@@ -28,64 +29,64 @@ import NotFoundException from '../NotFoundException';
* @author alasdair@google.com (Alasdair Mackintosh)
*/
export default class EAN13Reader extends UPCEANReader {
- private static FIRST_DIGIT_ENCODINGS: number[] = [0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A];
+ private static FIRST_DIGIT_ENCODINGS: number[] = [0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A];
private decodeMiddleCounters: Int32Array;
- public constructor() {
- super();
- this.decodeMiddleCounters = Int32Array.from([0, 0, 0, 0]);
- }
-
- public decodeMiddle(row: BitArray, startRange: Int32Array, resultString: string) {
- let counters = this.decodeMiddleCounters;
- counters[0] = 0;
- counters[1] = 0;
- counters[2] = 0;
- counters[3] = 0;
- let end = row.getSize();
- let rowOffset = startRange[1];
+ public constructor() {
+ super();
+ this.decodeMiddleCounters = Int32Array.from([0, 0, 0, 0]);
+ }
- let lgPatternFound = 0;
+ public decodeMiddle(row: BitArray, startRange: Int32Array, resultString: StringBuilder) {
+ let counters = this.decodeMiddleCounters;
+ counters[0] = 0;
+ counters[1] = 0;
+ counters[2] = 0;
+ counters[3] = 0;
+ let end = row.getSize();
+ let rowOffset = startRange[1];
- for (let x = 0; x < 6 && rowOffset < end; x++) {
- let bestMatch = UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_AND_G_PATTERNS);
- resultString += String.fromCharCode(('0'.charCodeAt(0) + bestMatch % 10));
- for (let counter of counters) {
- rowOffset += counter;
- }
- if (bestMatch >= 10) {
- lgPatternFound |= 1 << (5 - x);
- }
- }
+ let lgPatternFound = 0;
- resultString = EAN13Reader.determineFirstDigit(resultString, lgPatternFound);
+ for (let x = 0; x < 6 && rowOffset < end; x++) {
+ let bestMatch = UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_AND_G_PATTERNS);
+ resultString.append('0'.charCodeAt(0) + bestMatch % 10);
+ for (let counter of counters) {
+ rowOffset += counter;
+ }
+ if (bestMatch >= 10) {
+ lgPatternFound |= 1 << (5 - x);
+ }
+ }
- let middleRange = UPCEANReader.findGuardPattern(row, rowOffset, true, UPCEANReader.MIDDLE_PATTERN, new Int32Array(UPCEANReader.MIDDLE_PATTERN.length).fill(0));
- rowOffset = middleRange[1];
+ EAN13Reader.determineFirstDigit(resultString, lgPatternFound);
- for (let x = 0; x < 6 && rowOffset < end; x++) {
- let bestMatch = UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_PATTERNS);
- resultString += String.fromCharCode(('0'.charCodeAt(0) + bestMatch));
- for (let counter of counters) {
- rowOffset += counter;
- }
- }
+ let middleRange = UPCEANReader.findGuardPattern(row, rowOffset, true, UPCEANReader.MIDDLE_PATTERN, new Int32Array(UPCEANReader.MIDDLE_PATTERN.length));
+ rowOffset = middleRange[1];
- return {rowOffset, resultString};
+ for (let x = 0; x < 6 && rowOffset < end; x++) {
+ let bestMatch = UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_PATTERNS);
+ resultString.append('0'.charCodeAt(0) + bestMatch);
+ for (let counter of counters) {
+ rowOffset += counter;
+ }
}
- public getBarcodeFormat(): BarcodeFormat {
- return BarcodeFormat.EAN_13;
- }
+ return rowOffset;
+ }
+
+ public getBarcodeFormat(): BarcodeFormat {
+ return BarcodeFormat.EAN_13;
+ }
- static determineFirstDigit(resultString: string, lgPatternFound: number) {
- for (let d = 0; d < 10; d++) {
- if (lgPatternFound === this.FIRST_DIGIT_ENCODINGS[d]) {
- resultString = String.fromCharCode(('0'.charCodeAt(0) + d)) + resultString;
- return resultString;
- }
- }
- throw new NotFoundException();
+ static determineFirstDigit(resultString: StringBuilder, lgPatternFound: number) {
+ for (let d = 0; d < 10; d++) {
+ if (lgPatternFound === this.FIRST_DIGIT_ENCODINGS[d]) {
+ resultString.insert(0, '0'.charCodeAt(0) + d);
+ return;
+ }
}
+ throw new NotFoundException();
+ }
}
diff --git a/src/core/oned/EAN8Reader.ts b/src/core/oned/EAN8Reader.ts
index c49e55d5..71065c61 100644
--- a/src/core/oned/EAN8Reader.ts
+++ b/src/core/oned/EAN8Reader.ts
@@ -16,6 +16,7 @@
import BarcodeFormat from '../BarcodeFormat';
import BitArray from '../common/BitArray';
+import StringBuilder from '../util/StringBuilder';
import UPCEANReader from './UPCEANReader';
@@ -25,47 +26,46 @@ import UPCEANReader from './UPCEANReader';
* @author Sean Owen
*/
export default class EAN8Reader extends UPCEANReader {
- private decodeMiddleCounters: Int32Array;
+ private decodeMiddleCounters: Int32Array;
- public constructor() {
- super();
- this.decodeMiddleCounters = Int32Array.from([0, 0, 0, 0]);
- }
-
- public decodeMiddle(row: BitArray, startRange: Int32Array, resultString: string) {
- const counters = this.decodeMiddleCounters;
- counters[0] = 0;
- counters[1] = 0;
- counters[2] = 0;
- counters[3] = 0;
- let end = row.getSize();
- let rowOffset = startRange[1];
-
- for (let x = 0; x < 4 && rowOffset < end; x++) {
- let bestMatch = UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_PATTERNS);
- resultString += String.fromCharCode(('0'.charCodeAt(0) + bestMatch));
+ public constructor() {
+ super();
+ this.decodeMiddleCounters = Int32Array.from([0, 0, 0, 0]);
+ }
- for (let counter of counters) {
- rowOffset += counter;
- }
- }
+ public decodeMiddle(row: BitArray, startRange: Int32Array, resultString: StringBuilder) {
+ const counters = this.decodeMiddleCounters;
+ counters[0] = 0;
+ counters[1] = 0;
+ counters[2] = 0;
+ counters[3] = 0;
+ let end = row.getSize();
+ let rowOffset = startRange[1];
+ for (let x = 0; x < 4 && rowOffset < end; x++) {
+ let bestMatch = UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_PATTERNS);
+ resultString.append('0'.charCodeAt(0) + bestMatch);
- let middleRange = UPCEANReader.findGuardPattern(row, rowOffset, true, UPCEANReader.MIDDLE_PATTERN, new Int32Array(UPCEANReader.MIDDLE_PATTERN.length).fill(0));
- rowOffset = middleRange[1];
+ for (let counter of counters) {
+ rowOffset += counter;
+ }
+ }
- for (let x = 0; x < 4 && rowOffset < end; x++) {
- let bestMatch = UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_PATTERNS);
- resultString += String.fromCharCode(('0'.charCodeAt(0) + bestMatch));
+ let middleRange = UPCEANReader.findGuardPattern(row, rowOffset, true, UPCEANReader.MIDDLE_PATTERN, new Int32Array(UPCEANReader.MIDDLE_PATTERN.length));
+ rowOffset = middleRange[1];
- for (let counter of counters) {
- rowOffset += counter;
- }
- }
+ for (let x = 0; x < 4 && rowOffset < end; x++) {
+ let bestMatch = UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_PATTERNS);
+ resultString.append('0'.charCodeAt(0) + bestMatch);
- return {rowOffset, resultString};
+ for (let counter of counters) {
+ rowOffset += counter;
+ }
}
- public getBarcodeFormat(): BarcodeFormat {
- return BarcodeFormat.EAN_8;
- }
+ return rowOffset;
+ }
+
+ public getBarcodeFormat(): BarcodeFormat {
+ return BarcodeFormat.EAN_8;
+ }
}
diff --git a/src/core/oned/ITFReader.ts b/src/core/oned/ITFReader.ts
index e52e2535..9fb0e40d 100644
--- a/src/core/oned/ITFReader.ts
+++ b/src/core/oned/ITFReader.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.oned {*/
+/* namespace com.google.zxing.oned { */
import BarcodeFormat from '../BarcodeFormat';
import BitArray from '../common/BitArray';
@@ -39,60 +39,59 @@ export default class ITFReader extends OneDReader {
// private static w = 2; // Pixel width of a 2x wide line
// private static N = 1; // Pixed width of a narrow line
- private static PATTERNS: Int32Array[] = [
- Int32Array.from([1, 1, 2, 2, 1]), // 0
- Int32Array.from([2, 1, 1, 1, 2]), // 1
- Int32Array.from([1, 2, 1, 1, 2]), // 2
- Int32Array.from([2, 2, 1, 1, 1]), // 3
- Int32Array.from([1, 1, 2, 1, 2]), // 4
- Int32Array.from([2, 1, 2, 1, 1]), // 5
- Int32Array.from([1, 2, 2, 1, 1]), // 6
- Int32Array.from([1, 1, 1, 2, 2]), // 7
- Int32Array.from([2, 1, 1, 2, 1]), // 8
- Int32Array.from([1, 2, 1, 2, 1]), // 9
- Int32Array.from([1, 1, 3, 3, 1]), // 0
- Int32Array.from([3, 1, 1, 1, 3]), // 1
- Int32Array.from([1, 3, 1, 1, 3]), // 2
- Int32Array.from([3, 3, 1, 1, 1]), // 3
- Int32Array.from([1, 1, 3, 1, 3]), // 4
- Int32Array.from([3, 1, 3, 1, 1]), // 5
- Int32Array.from([1, 3, 3, 1, 1]), // 6
- Int32Array.from([1, 1, 1, 3, 3]), // 7
- Int32Array.from([3, 1, 1, 3, 1]), // 8
- Int32Array.from([1, 3, 1, 3, 1]) // 9
- ];
+ private static PATTERNS: Int32Array[] = [
+ Int32Array.from([1, 1, 2, 2, 1]), // 0
+ Int32Array.from([2, 1, 1, 1, 2]), // 1
+ Int32Array.from([1, 2, 1, 1, 2]), // 2
+ Int32Array.from([2, 2, 1, 1, 1]), // 3
+ Int32Array.from([1, 1, 2, 1, 2]), // 4
+ Int32Array.from([2, 1, 2, 1, 1]), // 5
+ Int32Array.from([1, 2, 2, 1, 1]), // 6
+ Int32Array.from([1, 1, 1, 2, 2]), // 7
+ Int32Array.from([2, 1, 1, 2, 1]), // 8
+ Int32Array.from([1, 2, 1, 2, 1]), // 9
+ Int32Array.from([1, 1, 3, 3, 1]), // 0
+ Int32Array.from([3, 1, 1, 1, 3]), // 1
+ Int32Array.from([1, 3, 1, 1, 3]), // 2
+ Int32Array.from([3, 3, 1, 1, 1]), // 3
+ Int32Array.from([1, 1, 3, 1, 3]), // 4
+ Int32Array.from([3, 1, 3, 1, 1]), // 5
+ Int32Array.from([1, 3, 3, 1, 1]), // 6
+ Int32Array.from([1, 1, 1, 3, 3]), // 7
+ Int32Array.from([3, 1, 1, 3, 1]), // 8
+ Int32Array.from([1, 3, 1, 3, 1]) // 9
+ ];
private static MAX_AVG_VARIANCE = 0.38;
private static MAX_INDIVIDUAL_VARIANCE = 0.5;
- /* /!** Valid ITF lengths. Anything longer than the largest value is also allowed. *!/*/
+ /* /!** Valid ITF lengths. Anything longer than the largest value is also allowed. *!/ */
private static DEFAULT_ALLOWED_LENGTHS: number[] = [6, 8, 10, 12, 14];
// Stores the actual narrow line width of the image being decoded.
private narrowLineWidth = -1;
- /*/!**
- * Start/end guard pattern.
- *
- * Note: The end pattern is reversed because the row is reversed before
- * searching for the END_PATTERN
- *!/*/
- private static START_PATTERN = Int32Array.from([1, 1, 1, 1]);
- private static END_PATTERN_REVERSED: Int32Array[] = [
- Int32Array.from([1, 1, 2]), // 2x
- Int32Array.from([1, 1, 3]) // 3x
- ];
+ /**
+ * Start/end guard pattern.
+ *
+ * Note: The end pattern is reversed because the row is reversed before
+ * searching for the END_PATTERN
+ */
+ private static START_PATTERN = Int32Array.from([1, 1, 1, 1]);
+ private static END_PATTERN_REVERSED: Int32Array[] = [
+ Int32Array.from([1, 1, 2]), // 2x
+ Int32Array.from([1, 1, 3]) // 3x
+ ];
// See ITFWriter.PATTERNS
/*
- /!**
+ /**
* Patterns of Wide / Narrow lines to indicate each digit
- *!/
- */
-
+ *
+ */
public decodeRow(rowNumber: number, row: BitArray, hints?: Map): Result {
// Find out where the Middle section (payload) starts & ends
@@ -149,13 +148,13 @@ export default class ITFReader extends OneDReader {
return resultReturn;
}
- /*
- /!**
+
+ /**
* @param row row of black/white values to search
* @param payloadStart offset of start pattern
* @param resultString {@link StringBuilder} to append decoded chars to
* @throws NotFoundException if decoding could not complete successfully
- *!/*/
+ */
private static decodeMiddle(
row: BitArray,
payloadStart: number,
@@ -169,9 +168,9 @@ export default class ITFReader extends OneDReader {
// Therefore, need to scan 10 lines and then
// split these into two arrays
- let counterDigitPair: Int32Array = new Int32Array(10); // 10
- let counterBlack: Int32Array = new Int32Array(5); // 5
- let counterWhite: Int32Array = new Int32Array(5); // 5
+ let counterDigitPair: Int32Array = new Int32Array(10); // 10
+ let counterBlack: Int32Array = new Int32Array(5); // 5
+ let counterWhite: Int32Array = new Int32Array(5); // 5
counterDigitPair.fill(0);
counterBlack.fill(0);
@@ -199,13 +198,13 @@ export default class ITFReader extends OneDReader {
}
}
- /*/!**
+ /**
* Identify where the start of the middle / payload section starts.
*
* @param row row of black/white values to search
* @return Array, containing index of start of 'start block' and end of
* 'start block'
- *!/*/
+ */
private decodeStart(row: BitArray): number[] {
let endStart = ITFReader.skipWhiteSpace(row);
@@ -221,7 +220,7 @@ export default class ITFReader extends OneDReader {
return startPattern;
}
- /*/!**
+ /**
* The start & end patterns must be pre/post fixed by a quiet zone. This
* zone must be at least 10 times the width of a narrow line. Scan back until
* we either get to the start of the barcode or match the necessary number of
@@ -235,7 +234,7 @@ export default class ITFReader extends OneDReader {
* @param row bit array representing the scanned barcode.
* @param startPattern index into row of the start or end pattern.
* @throws NotFoundException if the quiet zone cannot be found
- *!/*/
+ */
private validateQuietZone(row: BitArray, startPattern: number): void {
let quietCount: number = this.narrowLineWidth * 10; // expect to find this many pixels of quiet zone
@@ -254,14 +253,14 @@ export default class ITFReader extends OneDReader {
throw new NotFoundException();
}
}
- /*
- /!**
+
+ /**
* Skip all whitespace until we get to the first black line.
*
* @param row row of black/white values to search
* @return index of the first black line.
* @throws NotFoundException Throws exception if no black lines are found in the row
- *!/*/
+ */
private static skipWhiteSpace(row: BitArray): number {
const width = row.getSize();
@@ -274,13 +273,13 @@ export default class ITFReader extends OneDReader {
return endStart;
}
- /*/!**
+ /**
* Identify where the end of the middle / payload section ends.
*
* @param row row of black/white values to search
* @return Array, containing index of start of 'end block' and end of 'end
* block'
- *!/*/
+ */
private decodeEnd(row: BitArray): number[] {
// For convenience, reverse the row and then
@@ -319,26 +318,25 @@ export default class ITFReader extends OneDReader {
}
}
- /*
- /!**
- * @param row row of black/white values to search
- * @param rowOffset position to start search
- * @param pattern pattern of counts of number of black and white pixels that are
- * being searched for as a pattern
- * @return start/end horizontal offset of guard pattern, as an array of two
- * ints
- * @throws NotFoundException if pattern is not found
- *!/*/
- private static findGuardPattern(
- row: BitArray,
- rowOffset: number,
- pattern: Int32Array
- ): number[] {
-
- let patternLength: number = pattern.length;
- let counters: Int32Array = new Int32Array(patternLength);
- let width: number = row.getSize();
- let isWhite: boolean = false;
+ /**
+ * @param row row of black/white values to search
+ * @param rowOffset position to start search
+ * @param pattern pattern of counts of number of black and white pixels that are
+ * being searched for as a pattern
+ * @return start/end horizontal offset of guard pattern, as an array of two
+ * ints
+ * @throws NotFoundException if pattern is not found
+ */
+ private static findGuardPattern(
+ row: BitArray,
+ rowOffset: number,
+ pattern: Int32Array
+ ): number[] {
+
+ let patternLength: number = pattern.length;
+ let counters: Int32Array = new Int32Array(patternLength);
+ let width: number = row.getSize();
+ let isWhite: boolean = false;
let counterPosition: number = 0;
let patternStart: number = rowOffset;
@@ -368,15 +366,15 @@ export default class ITFReader extends OneDReader {
throw new NotFoundException();
}
- /*/!**
- * Attempts to decode a sequence of ITF black/white lines into single
- * digit.
- *
- * @param counters the counts of runs of observed black/white/black/... values
- * @return The decoded digit
- * @throws NotFoundException if digit cannot be decoded
- *!/*/
- private static decodeDigit(counters: Int32Array): number {
+ /**
+ * Attempts to decode a sequence of ITF black/white lines into single
+ * digit.
+ *
+ * @param counters the counts of runs of observed black/white/black/... values
+ * @return The decoded digit
+ * @throws NotFoundException if digit cannot be decoded
+ */
+ private static decodeDigit(counters: Int32Array): number {
let bestVariance: number = ITFReader.MAX_AVG_VARIANCE; // worst variance we'll accept
let bestMatch: number = -1;
@@ -402,5 +400,4 @@ export default class ITFReader extends OneDReader {
throw new NotFoundException();
}
}
-
}
diff --git a/src/core/oned/MultiFormatOneDReader.ts b/src/core/oned/MultiFormatOneDReader.ts
index d75118a7..bf113b40 100644
--- a/src/core/oned/MultiFormatOneDReader.ts
+++ b/src/core/oned/MultiFormatOneDReader.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.oned {*/
+/* namespace com.google.zxing.oned { */
import BarcodeFormat from '../BarcodeFormat';
import BitArray from '../common/BitArray';
@@ -53,7 +53,7 @@ export default class MultiFormatOneDReader extends OneDReader {
this.readers.push(new Code39Reader(useCode39CheckDigit));
}
// if (possibleFormats.includes(BarcodeFormat.CODE_93)) {
- // this.readers.push(new Code93Reader());
+ // this.readers.push(new Code93Reader());
// }
if (possibleFormats.includes(BarcodeFormat.CODE_128)) {
this.readers.push(new Code128Reader());
@@ -62,7 +62,7 @@ export default class MultiFormatOneDReader extends OneDReader {
this.readers.push(new ITFReader());
}
// if (possibleFormats.includes(BarcodeFormat.CODABAR)) {
- // this.readers.push(new CodaBarReader());
+ // this.readers.push(new CodaBarReader());
// }
if (possibleFormats.includes(BarcodeFormat.RSS_14)) {
this.readers.push(new RSS14Reader());
@@ -77,7 +77,6 @@ export default class MultiFormatOneDReader extends OneDReader {
this.readers.push(new Code39Reader());
// this.readers.push(new CodaBarReader());
// this.readers.push(new Code93Reader());
- this.readers.push(new MultiFormatUPCEANReader(hints));
this.readers.push(new Code128Reader());
this.readers.push(new ITFReader());
this.readers.push(new RSS14Reader());
diff --git a/src/core/oned/MultiFormatUPCEANReader.ts b/src/core/oned/MultiFormatUPCEANReader.ts
index 94455f5d..bf686ad8 100644
--- a/src/core/oned/MultiFormatUPCEANReader.ts
+++ b/src/core/oned/MultiFormatUPCEANReader.ts
@@ -26,7 +26,7 @@ import EAN8Reader from './EAN8Reader';
import UPCAReader from './UPCAReader';
import NotFoundException from '../NotFoundException';
import UPCEReader from './UPCEReader';
-import { Collection } from 'src/customTypings';
+import { Collection } from 'customTypings';
/**
* A reader that can read all available UPC/EAN formats. If a caller wants to try to
@@ -69,11 +69,13 @@ export default class MultiFormatUPCEANReader extends OneDReader {
this.readers = readers;
}
+ // @Override
public decodeRow(rowNumber: number, row: BitArray, hints?: Map): Result {
+ const startGuardPattern = UPCEANReader.findStartGuardPattern(row);
for (let reader of this.readers) {
try {
// const result: Result = reader.decodeRow(rowNumber, row, startGuardPattern, hints);
- const result = reader.decodeRow(rowNumber, row, hints);
+ const result = reader.decodeRow(rowNumber, row, startGuardPattern, hints);
// Special case: a 12-digit code encoded in UPC-A is identical to a "0"
// followed by those 12 digits encoded as EAN-13. Each will recognize such a code,
// UPC-A as a 12-digit string and EAN-13 as a 13-digit string starting with "0".
@@ -100,7 +102,6 @@ export default class MultiFormatUPCEANReader extends OneDReader {
const resultUPCA: Result = new Result(
result.getText().substring(1),
rawBytes,
- rawBytes.length,
result.getResultPoints(),
BarcodeFormat.UPC_A
);
diff --git a/src/core/oned/OneDReader.ts b/src/core/oned/OneDReader.ts
index 2969ff7d..87345fba 100644
--- a/src/core/oned/OneDReader.ts
+++ b/src/core/oned/OneDReader.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.oned {*/
+/* namespace com.google.zxing.oned { */
import BinaryBitmap from '../BinaryBitmap';
import BitArray from '../common/BitArray';
@@ -35,253 +35,255 @@ import NotFoundException from '../NotFoundException';
*/
export default abstract class OneDReader implements Reader {
- /*
- @Override
- public Result decode(BinaryBitmap image) throws NotFoundException, FormatException {
- return decode(image, null);
- }
- */
+ /*
+ @Override
+ public Result decode(BinaryBitmap image) throws NotFoundException, FormatException {
+ return decode(image, null);
+ }
+ */
- // Note that we don't try rotation without the try harder flag, even if rotation was supported.
- // @Override
- public decode(image: BinaryBitmap, hints?: Map): Result {
- try {
- return this.doDecode(image, hints);
- } catch (nfe) {
- const tryHarder = hints && (hints.get(DecodeHintType.TRY_HARDER) === true);
+ // Note that we don't try rotation without the try harder flag, even if rotation was supported.
+ // @Override
+ public decode(image: BinaryBitmap, hints?: Map): Result {
+ try {
+ return this.doDecode(image, hints);
+ } catch (nfe) {
+ const tryHarder = hints && (hints.get(DecodeHintType.TRY_HARDER) === true);
- if (tryHarder && image.isRotateSupported()) {
- const rotatedImage = image.rotateCounterClockwise();
- const result = this.doDecode(rotatedImage, hints);
- // Record that we found it rotated 90 degrees CCW / 270 degrees CW
- const metadata = result.getResultMetadata();
- let orientation = 270;
- if (metadata !== null && (metadata.get(ResultMetadataType.ORIENTATION) === true)) {
- // But if we found it reversed in doDecode(), add in that result here:
- orientation = (orientation + (metadata.get(ResultMetadataType.ORIENTATION) as number) % 360);
- }
- result.putMetadata(ResultMetadataType.ORIENTATION, orientation);
- // Update result points
- const points = result.getResultPoints();
- if (points !== null) {
- const height = rotatedImage.getHeight();
- for (let i = 0; i < points.length; i++) {
- points[i] = new ResultPoint(height - points[i].getY() - 1, points[i].getX());
- }
- }
- return result;
- } else {
- throw new NotFoundException();
- }
+ if (tryHarder && image.isRotateSupported()) {
+ const rotatedImage = image.rotateCounterClockwise();
+ const result = this.doDecode(rotatedImage, hints);
+ // Record that we found it rotated 90 degrees CCW / 270 degrees CW
+ const metadata = result.getResultMetadata();
+ let orientation = 270;
+ if (metadata !== null && (metadata.get(ResultMetadataType.ORIENTATION) === true)) {
+ // But if we found it reversed in doDecode(), add in that result here:
+ orientation = (orientation + (metadata.get(ResultMetadataType.ORIENTATION) as number) % 360);
+ }
+ result.putMetadata(ResultMetadataType.ORIENTATION, orientation);
+ // Update result points
+ const points = result.getResultPoints();
+ if (points !== null) {
+ const height = rotatedImage.getHeight();
+ for (let i = 0; i < points.length; i++) {
+ points[i] = new ResultPoint(height - points[i].getY() - 1, points[i].getX());
+ }
}
+ return result;
+ } else {
+ throw new NotFoundException();
+ }
}
+ }
- // @Override
- public reset(): void {
- // do nothing
- }
+ // @Override
+ public reset(): void {
+ // do nothing
+ }
- /**
- * We're going to examine rows from the middle outward, searching alternately above and below the
- * middle, and farther out each time. rowStep is the number of rows between each successive
- * attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then
- * middle + rowStep, then middle - (2 * rowStep), etc.
- * rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily
- * decided that moving up and down by about 1/16 of the image is pretty good; we try more of the
- * image if "trying harder".
- *
- * @param image The image to decode
- * @param hints Any hints that were requested
- * @return The contents of the decoded barcode
- * @throws NotFoundException Any spontaneous errors which occur
- */
- private doDecode(image: BinaryBitmap, hints?: Map): Result {
- const width = image.getWidth();
- const height = image.getHeight();
- let row = new BitArray(width);
+ /**
+ * We're going to examine rows from the middle outward, searching alternately above and below the
+ * middle, and farther out each time. rowStep is the number of rows between each successive
+ * attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then
+ * middle + rowStep, then middle - (2 * rowStep), etc.
+ * rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily
+ * decided that moving up and down by about 1/16 of the image is pretty good; we try more of the
+ * image if "trying harder".
+ *
+ * @param image The image to decode
+ * @param hints Any hints that were requested
+ * @return The contents of the decoded barcode
+ * @throws NotFoundException Any spontaneous errors which occur
+ */
+ private doDecode(image: BinaryBitmap, hints?: Map): Result {
+ const width = image.getWidth();
+ const height = image.getHeight();
+ let row = new BitArray(width);
- const tryHarder = hints && (hints.get(DecodeHintType.TRY_HARDER) === true);
- const rowStep = Math.max(1, height >> (tryHarder ? 8 : 5));
- let maxLines;
- if (tryHarder) {
- maxLines = height; // Look at the whole image, not just the center
- } else {
- maxLines = 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image
- }
+ const tryHarder = hints && (hints.get(DecodeHintType.TRY_HARDER) === true);
+ const rowStep = Math.max(1, height >> (tryHarder ? 8 : 5));
+ let maxLines;
+ if (tryHarder) {
+ maxLines = height; // Look at the whole image, not just the center
+ } else {
+ maxLines = 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image
+ }
- const middle = Math.trunc(height / 2);
- for (let x = 0; x < maxLines; x++) {
- // Scanning from the middle out. Determine which row we're looking at next:
- const rowStepsAboveOrBelow = Math.trunc((x + 1) / 2);
- const isAbove = (x & 0x01) === 0; // i.e. is x even?
- const rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
- if (rowNumber < 0 || rowNumber >= height) {
- // Oops, if we run off the top or bottom, stop
- break;
- }
+ const middle = Math.trunc(height / 2);
+ for (let x = 0; x < maxLines; x++) {
+ // Scanning from the middle out. Determine which row we're looking at next:
+ const rowStepsAboveOrBelow = Math.trunc((x + 1) / 2);
+ const isAbove = (x & 0x01) === 0; // i.e. is x even?
+ const rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
+ if (rowNumber < 0 || rowNumber >= height) {
+ // Oops, if we run off the top or bottom, stop
+ break;
+ }
- // Estimate black point for this row and load it:
- try {
- row = image.getBlackRow(rowNumber, row);
- } catch (ignored) { continue; }
+ // Estimate black point for this row and load it:
+ try {
+ row = image.getBlackRow(rowNumber, row);
+ } catch (ignored) {
+ continue;
+ }
- // While we have the image data in a BitArray, it's fairly cheap to reverse it in place to
- // handle decoding upside down barcodes.
- for (let attempt = 0; attempt < 2; attempt++) {
- if (attempt === 1) { // trying again?
- row.reverse(); // reverse the row and continue
+ // While we have the image data in a BitArray, it's fairly cheap to reverse it in place to
+ // handle decoding upside down barcodes.
+ for (let attempt = 0; attempt < 2; attempt++) {
+ if (attempt === 1) { // trying again?
+ row.reverse(); // reverse the row and continue
- // This means we will only ever draw result points *once* in the life of this method
- // since we want to avoid drawing the wrong points after flipping the row, and,
- // don't want to clutter with noise from every single row scan -- just the scans
- // that start on the center line.
- if (hints && (hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK) === true)) {
- const newHints = new Map();
- hints.forEach((hint, key) => newHints.set(key, hint));
- newHints.delete(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
- hints = newHints;
- }
- }
+ // This means we will only ever draw result points *once* in the life of this method
+ // since we want to avoid drawing the wrong points after flipping the row, and,
+ // don't want to clutter with noise from every single row scan -- just the scans
+ // that start on the center line.
+ if (hints && (hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK) === true)) {
+ const newHints = new Map();
+ hints.forEach((hint, key) => newHints.set(key, hint));
+ newHints.delete(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
+ hints = newHints;
+ }
+ }
- try {
- // Look for a barcode
- const result = this.decodeRow(rowNumber, row, hints);
- // We found our barcode
- if (attempt === 1) {
- // But it was upside down, so note that
- result.putMetadata(ResultMetadataType.ORIENTATION, 180);
- // And remember to flip the result points horizontally.
- const points = result.getResultPoints();
- if (points !== null) {
- points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY());
- points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY());
- }
- }
- return result;
- } catch (re) {
- // continue -- just couldn't decode this row
- }
+ try {
+ // Look for a barcode
+ const result = this.decodeRow(rowNumber, row, hints);
+ // We found our barcode
+ if (attempt === 1) {
+ // But it was upside down, so note that
+ result.putMetadata(ResultMetadataType.ORIENTATION, 180);
+ // And remember to flip the result points horizontally.
+ const points = result.getResultPoints();
+ if (points !== null) {
+ points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY());
+ points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY());
}
+ }
+ return result;
+ } catch (re) {
+ // continue -- just couldn't decode this row
}
-
- throw new NotFoundException();
+ }
}
- /**
- * Records the size of successive runs of white and black pixels in a row, starting at a given point.
- * The values are recorded in the given array, and the number of runs recorded is equal to the size
- * of the array. If the row starts on a white pixel at the given start point, then the first count
- * recorded is the run of white pixels starting from that point; likewise it is the count of a run
- * of black pixels if the row begin on a black pixels at that point.
- *
- * @param row row to count from
- * @param start offset into row to start at
- * @param counters array into which to record counts
- * @throws NotFoundException if counters cannot be filled entirely from row before running out
- * of pixels
- */
- protected static recordPattern(row: BitArray, start: number, counters: Int32Array): void {
- const numCounters = counters.length;
- for (let index = 0; index < numCounters; index++)
- counters[index] = 0;
+ throw new NotFoundException();
+ }
- const end = row.getSize();
- if (start >= end) {
- throw new NotFoundException();
- }
+ /**
+ * Records the size of successive runs of white and black pixels in a row, starting at a given point.
+ * The values are recorded in the given array, and the number of runs recorded is equal to the size
+ * of the array. If the row starts on a white pixel at the given start point, then the first count
+ * recorded is the run of white pixels starting from that point; likewise it is the count of a run
+ * of black pixels if the row begin on a black pixels at that point.
+ *
+ * @param row row to count from
+ * @param start offset into row to start at
+ * @param counters array into which to record counts
+ * @throws NotFoundException if counters cannot be filled entirely from row before running out
+ * of pixels
+ */
+ protected static recordPattern(row: BitArray, start: number, counters: Int32Array): void {
+ const numCounters = counters.length;
+ for (let index = 0; index < numCounters; index++)
+ counters[index] = 0;
- let isWhite = !row.get(start);
- let counterPosition = 0;
- let i = start;
- while (i < end) {
- if (row.get(i) !== isWhite) {
- counters[counterPosition]++;
- } else {
- if (++counterPosition === numCounters) {
- break;
- } else {
- counters[counterPosition] = 1;
- isWhite = !isWhite;
- }
- }
- i++;
- }
+ const end = row.getSize();
+ if (start >= end) {
+ throw new NotFoundException();
+ }
- // If we read fully the last section of pixels and filled up our counters -- or filled
- // the last counter but ran off the side of the image, OK. Otherwise, a problem.
- if (!(counterPosition === numCounters || (counterPosition === numCounters - 1 && i === end))) {
- throw new NotFoundException();
+ let isWhite = !row.get(start);
+ let counterPosition = 0;
+ let i = start;
+ while (i < end) {
+ if (row.get(i) !== isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (++counterPosition === numCounters) {
+ break;
+ } else {
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
}
+ }
+ i++;
}
- protected static recordPatternInReverse(row: BitArray, start: number, counters: Int32Array): void {
- // This could be more efficient I guess
- let numTransitionsLeft = counters.length;
- let last = row.get(start);
- while (start > 0 && numTransitionsLeft >= 0) {
- if (row.get(--start) !== last) {
- numTransitionsLeft--;
- last = !last;
- }
- }
- if (numTransitionsLeft >= 0) {
- throw new NotFoundException();
- }
+ // If we read fully the last section of pixels and filled up our counters -- or filled
+ // the last counter but ran off the side of the image, OK. Otherwise, a problem.
+ if (!(counterPosition === numCounters || (counterPosition === numCounters - 1 && i === end))) {
+ throw new NotFoundException();
+ }
+ }
- OneDReader.recordPattern(row, start + 1, counters);
+ protected static recordPatternInReverse(row: BitArray, start: number, counters: Int32Array): void {
+ // This could be more efficient I guess
+ let numTransitionsLeft = counters.length;
+ let last = row.get(start);
+ while (start > 0 && numTransitionsLeft >= 0) {
+ if (row.get(--start) !== last) {
+ numTransitionsLeft--;
+ last = !last;
+ }
+ }
+ if (numTransitionsLeft >= 0) {
+ throw new NotFoundException();
}
- /**
- * Determines how closely a set of observed counts of runs of black/white values matches a given
- * target pattern. This is reported as the ratio of the total variance from the expected pattern
- * proportions across all pattern elements, to the length of the pattern.
- *
- * @param counters observed counters
- * @param pattern expected pattern
- * @param maxIndividualVariance The most any counter can differ before we give up
- * @return ratio of total variance between counters and pattern compared to total pattern size
- */
- protected static patternMatchVariance(counters: Int32Array, pattern: Int32Array, maxIndividualVariance: number): number {
- const numCounters = counters.length;
- let total = 0;
- let patternLength = 0;
- for (let i = 0; i < numCounters; i++) {
- total += counters[i];
- patternLength += pattern[i];
- }
- if (total < patternLength) {
- // If we don't even have one pixel per unit of bar width, assume this is too small
- // to reliably match, so fail:
- return Number.POSITIVE_INFINITY;
- }
+ OneDReader.recordPattern(row, start + 1, counters);
+ }
+
+ /**
+ * Determines how closely a set of observed counts of runs of black/white values matches a given
+ * target pattern. This is reported as the ratio of the total variance from the expected pattern
+ * proportions across all pattern elements, to the length of the pattern.
+ *
+ * @param counters observed counters
+ * @param pattern expected pattern
+ * @param maxIndividualVariance The most any counter can differ before we give up
+ * @return ratio of total variance between counters and pattern compared to total pattern size
+ */
+ protected static patternMatchVariance(counters: Int32Array, pattern: Int32Array, maxIndividualVariance: number): number {
+ const numCounters = counters.length;
+ let total = 0;
+ let patternLength = 0;
+ for (let i = 0; i < numCounters; i++) {
+ total += counters[i];
+ patternLength += pattern[i];
+ }
+ if (total < patternLength) {
+ // If we don't even have one pixel per unit of bar width, assume this is too small
+ // to reliably match, so fail:
+ return Number.POSITIVE_INFINITY;
+ }
- const unitBarWidth = total / patternLength;
- maxIndividualVariance *= unitBarWidth;
+ const unitBarWidth = total / patternLength;
+ maxIndividualVariance *= unitBarWidth;
- let totalVariance = 0.0;
- for (let x = 0; x < numCounters; x++) {
- const counter = counters[x];
- const scaledPattern = pattern[x] * unitBarWidth;
- const variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;
- if (variance > maxIndividualVariance) {
- return Number.POSITIVE_INFINITY;
- }
- totalVariance += variance;
- }
- return totalVariance / total;
+ let totalVariance = 0.0;
+ for (let x = 0; x < numCounters; x++) {
+ const counter = counters[x];
+ const scaledPattern = pattern[x] * unitBarWidth;
+ const variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;
+ if (variance > maxIndividualVariance) {
+ return Number.POSITIVE_INFINITY;
+ }
+ totalVariance += variance;
}
+ return totalVariance / total;
+ }
- /**
- * Attempts to decode a one-dimensional barcode format given a single row of
- * an image.
- *
- * @param rowNumber row number from top of the row
- * @param row the black/white pixel data of the row
- * @param hints decode hints
- * @return {@link Result} containing encoded string and start/end of barcode
- * @throws NotFoundException if no potential barcode is found
- * @throws ChecksumException if a potential barcode is found but does not pass its checksum
- * @throws FormatException if a potential barcode is found but format is invalid
- */
- public abstract decodeRow(rowNumber: number, row: BitArray, hints?: Map): Result;
+ /**
+ * Attempts to decode a one-dimensional barcode format given a single row of
+ * an image.
+ *
+ * @param rowNumber row number from top of the row
+ * @param row the black/white pixel data of the row
+ * @param hints hints that influence decoding
+ * @return containing encoded string and start/end of barcode
+ * @throws {@link NotFoundException} if no potential barcode is found
+ * @throws {@link ChecksumException} if a potential barcode is found but does not pass its checksum
+ * @throws {@link FormatException} if a potential barcode is found but format is invalid
+ */
+ public abstract decodeRow(rowNumber: number, row: BitArray, hints?: Map): Result;
}
diff --git a/src/core/oned/UPCAReader.ts b/src/core/oned/UPCAReader.ts
index 49ea740d..e31d8e19 100644
--- a/src/core/oned/UPCAReader.ts
+++ b/src/core/oned/UPCAReader.ts
@@ -14,22 +14,19 @@
* limitations under the License.
*/
-/*namespace com.google.zxing.oned {*/
+/* namespace com.google.zxing.oned { */
import BarcodeFormat from '../BarcodeFormat';
import BinaryBitmap from '../BinaryBitmap';
import BitArray from '../common/BitArray';
import DecodeHintType from '../DecodeHintType';
+import StringBuilder from '../util/StringBuilder';
-import Reader from '../Reader';
import Result from '../Result';
-import ResultMetadataType from '../ResultMetadataType';
-import ResultPoint from '../ResultPoint';
import NotFoundException from '../NotFoundException';
import EAN13Reader from './EAN13Reader';
import UPCEANReader from './UPCEANReader';
-import { int } from 'src/customTypings';
/**
* Encapsulates functionality and implementation that is common to all families
@@ -58,20 +55,27 @@ export default class UPCAReader extends UPCEANReader {
return this.maybeReturnResult(this.ean13Reader.decode(image));
}
- // @Override
- public decodeRow(rowNumber: number, row: BitArray, hints?: Map): Result {
- return this.maybeReturnResult(this.ean13Reader.decodeRow(rowNumber, row, hints));
+ public decodeRow(rowNumber: number, row: BitArray, hints?: Map): Result;
+ public decodeRow(rowNumber: number, row: BitArray, startGuardRange: Int32Array, hints?: Map): Result;
+ public decodeRow(rowNumber: number, row: BitArray, arg3: Int32Array | Map, arg4?: Map): Result {
+ const startGuardRange = arg3 instanceof Int32Array ? arg3 : UPCEANReader.findStartGuardPattern(row);
+ const hints = arg3 instanceof Map ? arg3 : arg4;
+ return this.decodeRowImpl(rowNumber, row, startGuardRange, hints);
+ }
+
+ protected decodeRowImpl(rowNumber: number, row: BitArray, startGuardRange: Int32Array, hints?: Map): Result {
+ return this.maybeReturnResult(this.ean13Reader.decodeRow(rowNumber, row, startGuardRange, hints));
}
// @Override
- public decodeMiddle(row: BitArray, startRange: Int32Array, resultString: string) {
+ public decodeMiddle(row: BitArray, startRange: Int32Array, resultString: StringBuilder) {
return this.ean13Reader.decodeMiddle(row, startRange, resultString);
}
public maybeReturnResult(result: Result) {
let text = result.getText();
if (text.charAt(0) === '0') {
- let upcaResult = new Result(text.substring(1), null, null, result.getResultPoints(), BarcodeFormat.UPC_A);
+ let upcaResult = new Result(text.substring(1), null, null, BarcodeFormat.UPC_A);
if (result.getResultMetadata() != null) {
upcaResult.putAllMetadata(result.getResultMetadata());
}
diff --git a/src/core/oned/UPCEANExtension2Support.ts b/src/core/oned/UPCEANExtension2Support.ts
index 8008a12c..f4ce2d1d 100644
--- a/src/core/oned/UPCEANExtension2Support.ts
+++ b/src/core/oned/UPCEANExtension2Support.ts
@@ -16,6 +16,7 @@
import BarcodeFormat from '../BarcodeFormat';
import BitArray from '../common/BitArray';
+import StringBuilder from '../util/StringBuilder';
import AbstractUPCEANReader from './AbstractUPCEANReader';
import Result from '../Result';
@@ -27,74 +28,74 @@ import NotFoundException from '../NotFoundException';
* @see UPCEANExtension5Support
*/
export default class UPCEANExtension2Support {
- private decodeMiddleCounters = Int32Array.from([0, 0, 0, 0]);
- private decodeRowStringBuffer = '';
+ private decodeMiddleCounters = new Int32Array(4);
+ private decodeRowStringBuffer = new StringBuilder();
- public decodeRow(rowNumber: number, row: BitArray, extensionStartRange: Int32Array) {
- let result = this.decodeRowStringBuffer;
- let end = this.decodeMiddle(row, extensionStartRange, result);
+ public decodeRow(rowNumber: number, row: BitArray, extensionStartRange: Int32Array) {
+ let result = this.decodeRowStringBuffer;
+ let end = this.decodeMiddle(row, extensionStartRange, result);
- let resultString = result.toString();
- let extensionData = UPCEANExtension2Support.parseExtensionString(resultString);
+ let resultString = result.toString();
+ let extensionData = UPCEANExtension2Support.parseExtensionString(resultString);
- let resultPoints = [
- new ResultPoint((extensionStartRange[0] + extensionStartRange[1]) / 2.0, rowNumber),
- new ResultPoint(end, rowNumber)
- ];
+ let resultPoints = [
+ new ResultPoint((extensionStartRange[0] + extensionStartRange[1]) / 2.0, rowNumber),
+ new ResultPoint(end, rowNumber)
+ ];
- let extensionResult = new Result(resultString, null, 0, resultPoints, BarcodeFormat.UPC_EAN_EXTENSION, new Date().getTime());
+ let extensionResult = new Result(resultString, null, 0, resultPoints, BarcodeFormat.UPC_EAN_EXTENSION, new Date().getTime());
- if (extensionData != null) {
- extensionResult.putAllMetadata(extensionData);
- }
+ if (extensionData != null) {
+ extensionResult.putAllMetadata(extensionData);
+ }
+
+ return extensionResult;
+ }
+
+ public decodeMiddle(row: BitArray, startRange: Int32Array, resultString: StringBuilder) {
+ let counters = this.decodeMiddleCounters;
+ counters[0] = 0;
+ counters[1] = 0;
+ counters[2] = 0;
+ counters[3] = 0;
+ let end = row.getSize();
+ let rowOffset = startRange[1];
+
+ let checkParity = 0;
+
+ for (let x = 0; x < 2 && rowOffset < end; x++) {
+ let bestMatch = AbstractUPCEANReader.decodeDigit(row, counters, rowOffset, AbstractUPCEANReader.L_AND_G_PATTERNS);
+ resultString.append('0'.charCodeAt(0) + bestMatch % 10);
+ for (let counter of counters) {
+ rowOffset += counter;
+ }
+ if (bestMatch >= 10) {
+ checkParity |= 1 << (1 - x);
+ }
+ if (x !== 1) {
+ // Read off separator if not last
+ rowOffset = row.getNextSet(rowOffset);
+ rowOffset = row.getNextUnset(rowOffset);
+ }
+ }
- return extensionResult;
+ if (resultString.length() !== 2) {
+ throw new NotFoundException();
}
- public decodeMiddle(row: BitArray, startRange: Int32Array, resultString: string) {
- let counters = this.decodeMiddleCounters;
- counters[0] = 0;
- counters[1] = 0;
- counters[2] = 0;
- counters[3] = 0;
- let end = row.getSize();
- let rowOffset = startRange[1];
-
- let checkParity = 0;
-
- for (let x = 0; x < 2 && rowOffset < end; x++) {
- let bestMatch = AbstractUPCEANReader.decodeDigit(row, counters, rowOffset, AbstractUPCEANReader.L_AND_G_PATTERNS);
- resultString += String.fromCharCode(('0'.charCodeAt(0) + bestMatch % 10));
- for (let counter of counters) {
- rowOffset += counter;
- }
- if (bestMatch >= 10) {
- checkParity |= 1 << (1 - x);
- }
- if (x !== 1) {
- // Read off separator if not last
- rowOffset = row.getNextSet(rowOffset);
- rowOffset = row.getNextUnset(rowOffset);
- }
- }
-
- if (resultString.length !== 2) {
- throw new NotFoundException();
- }
-
- if (parseInt(resultString.toString()) % 4 !== checkParity) {
- throw new NotFoundException();
- }
-
- return rowOffset;
+ if (parseInt(resultString.toString()) % 4 !== checkParity) {
+ throw new NotFoundException();
}
- static parseExtensionString(raw: string) {
- if (raw.length !== 2) {
- return null;
- }
+ return rowOffset;
+ }
- return new Map([[ResultMetadataType.ISSUE_NUMBER, parseInt(raw)]]);
+ static parseExtensionString(raw: string) {
+ if (raw.length !== 2) {
+ return null;
}
+
+ return new Map([[ResultMetadataType.ISSUE_NUMBER, parseInt(raw)]]);
+ }
}
diff --git a/src/core/oned/UPCEANExtension5Support.ts b/src/core/oned/UPCEANExtension5Support.ts
index 8765b513..574fbff5 100644
--- a/src/core/oned/UPCEANExtension5Support.ts
+++ b/src/core/oned/UPCEANExtension5Support.ts
@@ -16,6 +16,7 @@
import BarcodeFormat from '../BarcodeFormat';
import BitArray from '../common/BitArray';
+import StringBuilder from '../util/StringBuilder';
// import UPCEANReader from './UPCEANReader';
import AbstractUPCEANReader from './AbstractUPCEANReader';
@@ -28,138 +29,138 @@ import NotFoundException from '../NotFoundException';
* @see UPCEANExtension2Support
*/
export default class UPCEANExtension5Support {
- private CHECK_DIGIT_ENCODINGS = [0x18, 0x14, 0x12, 0x11, 0x0C, 0x06, 0x03, 0x0A, 0x09, 0x05];
- private decodeMiddleCounters = Int32Array.from([0, 0, 0, 0]);
- private decodeRowStringBuffer = '';
+ private CHECK_DIGIT_ENCODINGS = [0x18, 0x14, 0x12, 0x11, 0x0C, 0x06, 0x03, 0x0A, 0x09, 0x05];
+ private decodeMiddleCounters = new Int32Array(4);
+ private decodeRowStringBuffer = new StringBuilder();
- public decodeRow(rowNumber: number, row: BitArray, extensionStartRange: Int32Array): Result {
- let result = this.decodeRowStringBuffer;
- let end = this.decodeMiddle(row, extensionStartRange, result);
+ public decodeRow(rowNumber: number, row: BitArray, extensionStartRange: Int32Array): Result {
+ let result = this.decodeRowStringBuffer;
+ let end = this.decodeMiddle(row, extensionStartRange, result);
- let resultString = result.toString();
- let extensionData = UPCEANExtension5Support.parseExtensionString(resultString);
+ let resultString = result.toString();
+ let extensionData = UPCEANExtension5Support.parseExtensionString(resultString);
- let resultPoints = [
- new ResultPoint((extensionStartRange[0] + extensionStartRange[1]) / 2.0, rowNumber),
- new ResultPoint(end, rowNumber)
- ];
+ let resultPoints = [
+ new ResultPoint((extensionStartRange[0] + extensionStartRange[1]) / 2.0, rowNumber),
+ new ResultPoint(end, rowNumber)
+ ];
- let extensionResult = new Result(resultString, null, 0, resultPoints, BarcodeFormat.UPC_EAN_EXTENSION, new Date().getTime());
+ let extensionResult = new Result(resultString, null, 0, resultPoints, BarcodeFormat.UPC_EAN_EXTENSION, new Date().getTime());
- if (extensionData != null) {
- extensionResult.putAllMetadata(extensionData);
- }
+ if (extensionData != null) {
+ extensionResult.putAllMetadata(extensionData);
+ }
- return extensionResult;
+ return extensionResult;
+ }
+
+ public decodeMiddle(row: BitArray, startRange: Int32Array, resultString: StringBuilder) {
+ let counters = this.decodeMiddleCounters;
+ counters[0] = 0;
+ counters[1] = 0;
+ counters[2] = 0;
+ counters[3] = 0;
+ let end = row.getSize();
+ let rowOffset = startRange[1];
+
+ let lgPatternFound = 0;
+
+ for (let x = 0; x < 5 && rowOffset < end; x++) {
+ let bestMatch = AbstractUPCEANReader.decodeDigit(row, counters, rowOffset, AbstractUPCEANReader.L_AND_G_PATTERNS);
+ resultString.append('0'.charCodeAt(0) + bestMatch % 10);
+ for (let counter of counters) {
+ rowOffset += counter;
+ }
+ if (bestMatch >= 10) {
+ lgPatternFound |= 1 << (4 - x);
+ }
+ if (x !== 4) {
+ // Read off separator if not last
+ rowOffset = row.getNextSet(rowOffset);
+ rowOffset = row.getNextUnset(rowOffset);
+ }
}
- public decodeMiddle(row: BitArray, startRange: Int32Array, resultString: string) {
- let counters = this.decodeMiddleCounters;
- counters[0] = 0;
- counters[1] = 0;
- counters[2] = 0;
- counters[3] = 0;
- let end = row.getSize();
- let rowOffset = startRange[1];
-
- let lgPatternFound = 0;
-
- for (let x = 0; x < 5 && rowOffset < end; x++) {
- let bestMatch = AbstractUPCEANReader.decodeDigit(row, counters, rowOffset, AbstractUPCEANReader.L_AND_G_PATTERNS);
- resultString += String.fromCharCode(('0'.charCodeAt(0) + bestMatch % 10));
- for (let counter of counters) {
- rowOffset += counter;
- }
- if (bestMatch >= 10) {
- lgPatternFound |= 1 << (4 - x);
- }
- if (x !== 4) {
- // Read off separator if not last
- rowOffset = row.getNextSet(rowOffset);
- rowOffset = row.getNextUnset(rowOffset);
- }
- }
+ if (resultString.length() !== 5) {
+ throw new NotFoundException();
+ }
- if (resultString.length !== 5) {
- throw new NotFoundException();
- }
+ let checkDigit = this.determineCheckDigit(lgPatternFound);
+ if (UPCEANExtension5Support.extensionChecksum(resultString.toString()) !== checkDigit) {
+ throw new NotFoundException();
+ }
- let checkDigit = this.determineCheckDigit(lgPatternFound);
- if (UPCEANExtension5Support.extensionChecksum(resultString.toString()) !== checkDigit) {
- throw new NotFoundException();
- }
+ return rowOffset;
+ }
- return rowOffset;
+ static extensionChecksum(s: string) {
+ let length = s.length;
+ let sum = 0;
+ for (let i = length - 2; i >= 0; i -= 2) {
+ sum += s.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
}
-
- static extensionChecksum(s: string) {
- let length = s.length;
- let sum = 0;
- for (let i = length - 2; i >= 0; i -= 2) {
- sum += s.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
- }
- sum *= 3;
- for (let i = length - 1; i >= 0; i -= 2) {
- sum += s.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
- }
- sum *= 3;
- return sum % 10;
+ sum *= 3;
+ for (let i = length - 1; i >= 0; i -= 2) {
+ sum += s.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
}
-
- public determineCheckDigit(lgPatternFound: number) {
- for (let d = 0; d < 10; d++) {
- if (lgPatternFound === this.CHECK_DIGIT_ENCODINGS[d]) {
- return d;
- }
- }
- throw new NotFoundException();
+ sum *= 3;
+ return sum % 10;
+ }
+
+ public determineCheckDigit(lgPatternFound: number) {
+ for (let d = 0; d < 10; d++) {
+ if (lgPatternFound === this.CHECK_DIGIT_ENCODINGS[d]) {
+ return d;
+ }
}
+ throw new NotFoundException();
+ }
- static parseExtensionString(raw: string) {
- if (raw.length !== 5) {
- return null;
- }
- let value = UPCEANExtension5Support.parseExtension5String(raw);
- if (value == null) {
- return null;
- }
-
- return new Map([[ResultMetadataType.SUGGESTED_PRICE, value]]);
+ static parseExtensionString(raw: string) {
+ if (raw.length !== 5) {
+ return null;
+ }
+ let value = UPCEANExtension5Support.parseExtension5String(raw);
+ if (value == null) {
+ return null;
}
- static parseExtension5String(raw: string) {
- let currency;
- switch (raw.charAt(0)) {
- case '0':
- currency = '£';
- break;
- case '5':
- currency = '$';
- break;
- case '9':
- // Reference: http://www.jollytech.com
- switch (raw) {
- case '90000':
- // No suggested retail price
- return null;
- case '99991':
- // Complementary
- return '0.00';
- case '99990':
- return 'Used';
- }
- // Otherwise... unknown currency?
- currency = '';
- break;
- default:
- currency = '';
- break;
+ return new Map([[ResultMetadataType.SUGGESTED_PRICE, value]]);
+ }
+
+ static parseExtension5String(raw: string) {
+ let currency;
+ switch (raw.charAt(0)) {
+ case '0':
+ currency = '£';
+ break;
+ case '5':
+ currency = '$';
+ break;
+ case '9':
+ // Reference: http://www.jollytech.com
+ switch (raw) {
+ case '90000':
+ // No suggested retail price
+ return null;
+ case '99991':
+ // Complementary
+ return '0.00';
+ case '99990':
+ return 'Used';
}
- let rawAmount = parseInt(raw.substring(1));
- let unitsString = (rawAmount / 100).toString();
- let hundredths = rawAmount % 100;
- let hundredthsString = hundredths < 10 ? '0' + hundredths : hundredths.toString(); // fixme
- return currency + unitsString + '.' + hundredthsString;
+ // Otherwise... unknown currency?
+ currency = '';
+ break;
+ default:
+ currency = '';
+ break;
}
+ let rawAmount = parseInt(raw.substring(1));
+ let unitsString = (rawAmount / 100).toString();
+ let hundredths = rawAmount % 100;
+ let hundredthsString = hundredths < 10 ? '0' + hundredths : hundredths.toString(); // fixme
+ return currency + unitsString + '.' + hundredthsString;
+ }
}
diff --git a/src/core/oned/UPCEANExtensionSupport.ts b/src/core/oned/UPCEANExtensionSupport.ts
index 21e19089..4359c071 100644
--- a/src/core/oned/UPCEANExtensionSupport.ts
+++ b/src/core/oned/UPCEANExtensionSupport.ts
@@ -21,18 +21,18 @@ import UPCEANExtension2Support from './UPCEANExtension2Support';
import Result from '../Result';
export default class UPCEANExtensionSupport {
- private static EXTENSION_START_PATTERN = Int32Array.from([1, 1, 2]);
+ private static EXTENSION_START_PATTERN = Int32Array.from([1, 1, 2]);
- static decodeRow(rowNumber: number, row: BitArray, rowOffset: number): Result {
- let extensionStartRange = AbstractUPCEANReader.findGuardPattern(row, rowOffset, false, this.EXTENSION_START_PATTERN, new Int32Array(this.EXTENSION_START_PATTERN.length).fill(0));
- try {
- // return null;
- let fiveSupport = new UPCEANExtension5Support();
- return fiveSupport.decodeRow(rowNumber, row, extensionStartRange);
- } catch (err) {
- // return null;
- let twoSupport = new UPCEANExtension2Support();
- return twoSupport.decodeRow(rowNumber, row, extensionStartRange);
- }
+ static decodeRow(rowNumber: number, row: BitArray, rowOffset: number): Result {
+ let extensionStartRange = AbstractUPCEANReader.findGuardPattern(row, rowOffset, false, this.EXTENSION_START_PATTERN, new Int32Array(this.EXTENSION_START_PATTERN.length));
+ try {
+ // return null;
+ let fiveSupport = new UPCEANExtension5Support();
+ return fiveSupport.decodeRow(rowNumber, row, extensionStartRange);
+ } catch (err) {
+ // return null;
+ let twoSupport = new UPCEANExtension2Support();
+ return twoSupport.decodeRow(rowNumber, row, extensionStartRange);
}
+ }
}
diff --git a/src/core/oned/UPCEANReader.ts b/src/core/oned/UPCEANReader.ts
index cc70395e..3d7089a6 100644
--- a/src/core/oned/UPCEANReader.ts
+++ b/src/core/oned/UPCEANReader.ts
@@ -28,8 +28,8 @@ import FormatException from '../FormatException';
import ChecksumException from '../ChecksumException';
/**
- * Encapsulates functionality and implementation that is common to UPC and EAN families
- * of one-dimensional barcodes.
+ * Encapsulates functionality and implementation that is common to UPC and EAN families
+ * of one-dimensional barcodes.
*
* @author dswitkin@google.com (Daniel Switkin)
* @author Sean Owen
@@ -37,140 +37,110 @@ import ChecksumException from '../ChecksumException';
*/
export default abstract class UPCEANReader extends AbstractUPCEANReader {
- public constructor() {
- super();
- this.decodeRowStringBuffer = '';
+ public constructor() {
+ super();
- UPCEANReader.L_AND_G_PATTERNS = UPCEANReader.L_PATTERNS.map(arr => Int32Array.from(arr));
+ UPCEANReader.L_AND_G_PATTERNS = UPCEANReader.L_PATTERNS.map(arr => Int32Array.from(arr));
- for (let i = 10; i < 20; i++) {
- let widths = UPCEANReader.L_PATTERNS[i - 10];
- let reversedWidths = new Int32Array(widths.length);
- for (let j = 0; j < widths.length; j++) {
- reversedWidths[j] = widths[widths.length - j - 1];
- }
- UPCEANReader.L_AND_G_PATTERNS[i] = reversedWidths;
- }
+ for (let i = 10; i < 20; i++) {
+ let widths = UPCEANReader.L_PATTERNS[i - 10];
+ let reversedWidths = new Int32Array(widths.length);
+ for (let j = 0; j < widths.length; j++) {
+ reversedWidths[j] = widths[widths.length - j - 1];
+ }
+ UPCEANReader.L_AND_G_PATTERNS[i] = reversedWidths;
+ }
+ }
+
+ public decodeRow(rowNumber: number, row: BitArray, hints?: Map): Result;
+ public decodeRow(rowNumber: number, row: BitArray, startGuardRange: Int32Array, hints?: Map): Result;
+ public decodeRow(rowNumber: number, row: BitArray, arg3: Int32Array | Map, arg4?: Map): Result {
+ const startGuardRange = arg3 instanceof Int32Array ? arg3 : UPCEANReader.findStartGuardPattern(row);
+ const hints = arg3 instanceof Map ? arg3 : arg4;
+ return this.decodeRowImpl(rowNumber, row, startGuardRange, hints);
+ }
+
+ protected decodeRowImpl(rowNumber: number, row: BitArray, startGuardRange: Int32Array, hints?: Map): Result {
+ let resultPointCallback = hints == null ? null : hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
+
+ if (resultPointCallback != null) {
+ const resultPoint = new ResultPoint((startGuardRange[0] + startGuardRange[1]) / 2.0, rowNumber);
+ resultPointCallback.foundPossibleResultPoint(resultPoint);
}
- public decodeRow(rowNumber: number, row: BitArray, hints?: Map): Result {
- let startGuardRange = UPCEANReader.findStartGuardPattern(row);
- let resultPointCallback = hints == null ? null : hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
-
- if (resultPointCallback != null) {
- const resultPoint = new ResultPoint((startGuardRange[0] + startGuardRange[1]) / 2.0, rowNumber);
- resultPointCallback.foundPossibleResultPoint(resultPoint);
- }
-
- let budello = this.decodeMiddle(row, startGuardRange, this.decodeRowStringBuffer);
- let endStart = budello.rowOffset;
- let result = budello.resultString;
-
- if (resultPointCallback != null) {
- const resultPoint = new ResultPoint(endStart, rowNumber);
- resultPointCallback.foundPossibleResultPoint(resultPoint);
- }
-
- let endRange = UPCEANReader.decodeEnd(row, endStart);
-
- if (resultPointCallback != null) {
- const resultPoint = new ResultPoint((endRange[0] + endRange[1]) / 2.0, rowNumber);
- resultPointCallback.foundPossibleResultPoint(resultPoint);
- }
-
- // Make sure there is a quiet zone at least as big as the end pattern after the barcode. The
- // spec might want more whitespace, but in practice this is the maximum we can count on.
- let end = endRange[1];
- let quietEnd = end + (end - endRange[0]);
-
- if (quietEnd >= row.getSize() || !row.isRange(end, quietEnd, false)) {
- throw new NotFoundException();
- }
+ let result = this.decodeRowStringBuffer;
+ result.setLengthToZero();
+ let endStart = this.decodeMiddle(row, startGuardRange, result);
- let resultString = result.toString();
- // UPC/EAN should never be less than 8 chars anyway
- if (resultString.length < 8) {
- throw new FormatException();
- }
- if (!UPCEANReader.checkChecksum(resultString)) {
- throw new ChecksumException();
- }
+ if (resultPointCallback != null) {
+ const resultPoint = new ResultPoint(endStart, rowNumber);
+ resultPointCallback.foundPossibleResultPoint(resultPoint);
+ }
- let left = (startGuardRange[1] + startGuardRange[0]) / 2.0;
- let right = (endRange[1] + endRange[0]) / 2.0;
- let format = this.getBarcodeFormat();
- let resultPoint = [new ResultPoint(left, rowNumber), new ResultPoint(right, rowNumber)];
- let decodeResult = new Result(resultString, null, 0, resultPoint, format, new Date().getTime());
-
- let extensionLength = 0;
-
- try {
- let extensionResult = UPCEANExtensionSupport.decodeRow(rowNumber, row, endRange[1]);
- decodeResult.putMetadata(ResultMetadataType.UPC_EAN_EXTENSION, extensionResult.getText());
- decodeResult.putAllMetadata(extensionResult.getResultMetadata());
- decodeResult.addResultPoints(extensionResult.getResultPoints());
- extensionLength = extensionResult.getText().length;
- } catch (err) {
- }
+ let endRange = this.decodeEnd(row, endStart);
- let allowedExtensions = hints == null ? null : hints.get(DecodeHintType.ALLOWED_EAN_EXTENSIONS);
- if (allowedExtensions != null) {
- let valid = false;
- for (let length in allowedExtensions) {
- if (extensionLength.toString() === length) { // check me
- valid = true;
- break;
- }
- }
- if (!valid) {
- throw new NotFoundException();
- }
- }
+ if (resultPointCallback != null) {
+ const resultPoint = new ResultPoint((endRange[0] + endRange[1]) / 2.0, rowNumber);
+ resultPointCallback.foundPossibleResultPoint(resultPoint);
+ }
- if (format === BarcodeFormat.EAN_13 || format === BarcodeFormat.UPC_A) {
- // let countryID = eanManSupport.lookupContryIdentifier(resultString); todo
- // if (countryID != null) {
- // decodeResult.putMetadata(ResultMetadataType.POSSIBLE_COUNTRY, countryID);
- // }
- }
+ // Make sure there is a quiet zone at least as big as the end pattern after the barcode. The
+ // spec might want more whitespace, but in practice this is the maximum we can count on.
+ let end = endRange[1];
+ let quietEnd = end + (end - endRange[0]);
- return decodeResult;
+ if (quietEnd >= row.getSize() || !row.isRange(end, quietEnd, false)) {
+ throw new NotFoundException();
}
- static checkChecksum(s: string): boolean {
- return UPCEANReader.checkStandardUPCEANChecksum(s);
+ let resultString = result.toString();
+ // UPC/EAN should never be less than 8 chars anyway
+ if (resultString.length < 8) {
+ throw new FormatException();
+ }
+ if (!UPCEANReader.checkChecksum(resultString)) {
+ throw new ChecksumException();
}
- static checkStandardUPCEANChecksum(s: string): boolean {
- let length = s.length;
- if (length === 0) return false;
-
- let check = parseInt(s.charAt(length - 1), 10);
- return UPCEANReader.getStandardUPCEANChecksum(s.substring(0, length - 1)) === check;
+ let left = (startGuardRange[1] + startGuardRange[0]) / 2.0;
+ let right = (endRange[1] + endRange[0]) / 2.0;
+ let format = this.getBarcodeFormat();
+ let resultPoint = [new ResultPoint(left, rowNumber), new ResultPoint(right, rowNumber)];
+ let decodeResult = new Result(resultString, null, 0, resultPoint, format, new Date().getTime());
+
+ let extensionLength = 0;
+
+ try {
+ let extensionResult = UPCEANExtensionSupport.decodeRow(rowNumber, row, endRange[1]);
+ decodeResult.putMetadata(ResultMetadataType.UPC_EAN_EXTENSION, extensionResult.getText());
+ decodeResult.putAllMetadata(extensionResult.getResultMetadata());
+ decodeResult.addResultPoints(extensionResult.getResultPoints());
+ extensionLength = extensionResult.getText().length;
+ } catch (err) {
}
- static getStandardUPCEANChecksum(s: string): number {
- let length = s.length;
- let sum = 0;
- for (let i = length - 1; i >= 0; i -= 2) {
- let digit = s.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
- if (digit < 0 || digit > 9) {
- throw new FormatException();
- }
- sum += digit;
- }
- sum *= 3;
- for (let i = length - 2; i >= 0; i -= 2) {
- let digit = s.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
- if (digit < 0 || digit > 9) {
- throw new FormatException();
- }
- sum += digit;
+ let allowedExtensions = hints == null ? null : hints.get(DecodeHintType.ALLOWED_EAN_EXTENSIONS);
+ if (allowedExtensions != null) {
+ let valid = false;
+ for (let length in allowedExtensions) {
+ // Todo: investigate
+ if (extensionLength.toString() === length) { // check me
+ valid = true;
+ break;
}
- return (1000 - sum) % 10;
+ }
+ if (!valid) {
+ throw new NotFoundException();
+ }
}
- static decodeEnd(row: BitArray, endStart: number): Int32Array {
- return UPCEANReader.findGuardPattern(row, endStart, false, UPCEANReader.START_END_PATTERN, new Int32Array(UPCEANReader.START_END_PATTERN.length).fill(0));
+ if (format === BarcodeFormat.EAN_13 || format === BarcodeFormat.UPC_A) {
+ // let countryID = eanManSupport.lookupContryIdentifier(resultString); todo
+ // if (countryID != null) {
+ // decodeResult.putMetadata(ResultMetadataType.POSSIBLE_COUNTRY, countryID);
+ // }
}
+
+ return decodeResult;
+ }
}
diff --git a/src/core/oned/UPCEReader.ts b/src/core/oned/UPCEReader.ts
index 8381b11e..3890fe7c 100644
--- a/src/core/oned/UPCEReader.ts
+++ b/src/core/oned/UPCEReader.ts
@@ -19,7 +19,7 @@ import BitArray from '../common/BitArray';
import StringBuilder from '../util/StringBuilder';
import NotFoundException from '../NotFoundException';
import BarcodeFormat from '../BarcodeFormat';
-import { int, char } from 'src/customTypings';
+import { int, char } from 'customTypings';
// package com.google.zxing.oned;
@@ -44,8 +44,8 @@ export default /* final */ class UPCEReader extends UPCEANReader {
/**
* The pattern that marks the middle, and end, of a UPC-E pattern.
* There is no "second half" to a UPC-E barcode.
- */
- private static /*final*/ MIDDLE_END_PATTERN: Int32Array = Int32Array.from([1, 1, 1, 1, 1, 1]);
+ */
+ private static /* final */ MIDDLE_END_PATTERN: Int32Array = Int32Array.from([1, 1, 1, 1, 1, 1]);
// For an UPC-E barcode, the final digit is represented by the parities used
// to encode the middle six digits, according to the table below.
@@ -75,13 +75,13 @@ export default /* final */ class UPCEReader extends UPCEANReader {
* See {@link #L_AND_G_PATTERNS}; these values similarly represent patterns of
* even-odd parity encodings of digits that imply both the number system (0 or 1)
* used, and the check digit.
- */
- static /*final*/ NUMSYS_AND_CHECK_DIGIT_PATTERNS: Int32Array[] = [
+ */
+ static /* final */ NUMSYS_AND_CHECK_DIGIT_PATTERNS: Int32Array[] = [
Int32Array.from([0x38, 0x34, 0x32, 0x31, 0x2C, 0x26, 0x23, 0x2A, 0x29, 0x25]),
Int32Array.from([0x07, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1]),
];
- private /*final*/ decodeMiddleCounters: Int32Array;
+ private /* final */ decodeMiddleCounters: Int32Array;
public constructor() {
super();
@@ -90,10 +90,10 @@ export default /* final */ class UPCEReader extends UPCEANReader {
/**
* @throws NotFoundException
- */
+ */
// @Override
- public decodeMiddle(row: BitArray, startRange: Int32Array, result: string) {
- const counters: Int32Array = this.decodeMiddleCounters.map(x => x);
+ public decodeMiddle(row: BitArray, startRange: Int32Array, resultString: StringBuilder) {
+ const counters: Int32Array = new Int32Array(this.decodeMiddleCounters);
counters[0] = 0;
counters[1] = 0;
counters[2] = 0;
@@ -105,7 +105,7 @@ export default /* final */ class UPCEReader extends UPCEANReader {
for (let x: int = 0; x < 6 && rowOffset < end; x++) {
const bestMatch: int = UPCEReader.decodeDigit(row, counters, rowOffset, UPCEReader.L_AND_G_PATTERNS);
- result += String.fromCharCode(('0'.charCodeAt(0) + bestMatch % 10));
+ resultString.append('0'.charCodeAt(0) + bestMatch % 10);
for (let counter of counters) {
rowOffset += counter;
}
@@ -114,22 +114,22 @@ export default /* final */ class UPCEReader extends UPCEANReader {
}
}
- UPCEReader.determineNumSysAndCheckDigit(new StringBuilder(result), lgPatternFound);
+ UPCEReader.determineNumSysAndCheckDigit(resultString, lgPatternFound);
return rowOffset;
}
/**
* @throws NotFoundException
- */
+ */
// @Override
protected decodeEnd(row: BitArray, endStart: int): Int32Array {
- return UPCEReader.findGuardPatternWithoutCounters(row, endStart, true, UPCEReader.MIDDLE_END_PATTERN);
+ return UPCEReader.findGuardPattern(row, endStart, true, UPCEReader.MIDDLE_END_PATTERN);
}
/**
* @throws FormatException
- */
+ */
// @Override
protected checkChecksum(s: string): boolean {
return UPCEANReader.checkChecksum(UPCEReader.convertUPCEtoUPCA(s));
@@ -137,14 +137,13 @@ export default /* final */ class UPCEReader extends UPCEANReader {
/**
* @throws NotFoundException
- */
- private static determineNumSysAndCheckDigit(resultString: StringBuilder, lgPatternFound: int): void {
-
+ */
+ private static determineNumSysAndCheckDigit(resultString: StringBuilder, lgPatternFound: int) {
for (let numSys: int = 0; numSys <= 1; numSys++) {
for (let d: int = 0; d < 10; d++) {
if (lgPatternFound === this.NUMSYS_AND_CHECK_DIGIT_PATTERNS[numSys][d]) {
- resultString.insert(0, /*(char)*/('0' + numSys));
- resultString.append(/*(char)*/('0' + d));
+ resultString.insert(0, '0'.charCodeAt(0) + numSys);
+ resultString.append('0'.charCodeAt(0) + d);
return;
}
}
@@ -162,11 +161,11 @@ export default /* final */ class UPCEReader extends UPCEANReader {
*
* @param upce UPC-E code as string of digits
* @return equivalent UPC-A code as string of digits
- */
+ */
public static convertUPCEtoUPCA(upce: string): string {
// the following line is equivalent to upce.getChars(1, 7, upceChars, 0);
const upceChars = upce.slice(1, 7).split('').map(x => x.charCodeAt(0));
- const result: StringBuilder = new StringBuilder(/*12*/);
+ const result: StringBuilder = new StringBuilder(/* 12 */);
result.append(upce.charAt(0));
let lastChar: char = upceChars[5];
switch (lastChar) {
diff --git a/src/core/oned/rss/AbstractRSSReader.ts b/src/core/oned/rss/AbstractRSSReader.ts
index 7da91451..bdb745fb 100644
--- a/src/core/oned/rss/AbstractRSSReader.ts
+++ b/src/core/oned/rss/AbstractRSSReader.ts
@@ -12,30 +12,30 @@ export default abstract class AbstractRSSReader extends OneDReader {
private static readonly MIN_FINDER_PATTERN_RATIO: number = 9.5 / 12.0;
private static readonly MAX_FINDER_PATTERN_RATIO: number = 12.5 / 14.0;
- private readonly decodeFinderCounters: Int32Array;
- private readonly dataCharacterCounters: Int32Array;
- private readonly oddRoundingErrors: number[];
- private readonly evenRoundingErrors: number[];
- private readonly oddCounts: number[];
- private readonly evenCounts: number[];
-
- public constructor() {
- super();
- this.decodeFinderCounters = new Int32Array(4);
- this.dataCharacterCounters = new Int32Array(8);
- this.oddRoundingErrors = new Array(4);
- this.evenRoundingErrors = new Array(4);
- this.oddCounts = new Array(this.dataCharacterCounters.length / 2);
- this.evenCounts = new Array(this.dataCharacterCounters.length / 2);
- }
+ private readonly decodeFinderCounters: Int32Array;
+ private readonly dataCharacterCounters: Int32Array;
+ private readonly oddRoundingErrors: number[];
+ private readonly evenRoundingErrors: number[];
+ private readonly oddCounts: number[];
+ private readonly evenCounts: number[];
+
+ public constructor() {
+ super();
+ this.decodeFinderCounters = new Int32Array(4);
+ this.dataCharacterCounters = new Int32Array(8);
+ this.oddRoundingErrors = new Array(4);
+ this.evenRoundingErrors = new Array(4);
+ this.oddCounts = new Array(this.dataCharacterCounters.length / 2);
+ this.evenCounts = new Array(this.dataCharacterCounters.length / 2);
+ }
- protected getDecodeFinderCounters(): Int32Array {
- return this.decodeFinderCounters;
- }
+ protected getDecodeFinderCounters(): Int32Array {
+ return this.decodeFinderCounters;
+ }
- protected getDataCharacterCounters(): Int32Array {
- return this.dataCharacterCounters;
- }
+ protected getDataCharacterCounters(): Int32Array {
+ return this.dataCharacterCounters;
+ }
protected getOddRoundingErrors(): number[] {
return this.oddRoundingErrors;
@@ -66,7 +66,7 @@ export default abstract class AbstractRSSReader extends OneDReader {
* @param array values to sum
* @return sum of values
* @deprecated call {@link MathUtils#sum(int[])}
- */
+ */
protected static count(array: number[]) {
return MathUtils.sum(new Int32Array(array));
}
diff --git a/src/core/oned/rss/DataCharacter.ts b/src/core/oned/rss/DataCharacter.ts
index 49026803..75e0b784 100644
--- a/src/core/oned/rss/DataCharacter.ts
+++ b/src/core/oned/rss/DataCharacter.ts
@@ -1,34 +1,34 @@
export default class DataCharacter {
- private value: number;
- private checksumPortion: number;
+ private value: number;
+ private checksumPortion: number;
- public constructor(value: number, checksumPortion: number) {
- this.value = value;
- this.checksumPortion = checksumPortion;
- }
+ public constructor(value: number, checksumPortion: number) {
+ this.value = value;
+ this.checksumPortion = checksumPortion;
+ }
- public getValue(): number {
- return this.value;
- }
+ public getValue(): number {
+ return this.value;
+ }
- public getChecksumPortion(): number {
- return this.checksumPortion;
- }
+ public getChecksumPortion(): number {
+ return this.checksumPortion;
+ }
- public toString(): string {
- return this.value + '(' + this.checksumPortion + ')';
- }
+ public toString(): string {
+ return this.value + '(' + this.checksumPortion + ')';
+ }
- public equals(o: object): boolean {
- if (!(o instanceof DataCharacter)) {
- return false;
- }
- const that = o;
- return this.value === that.value && this.checksumPortion === that.checksumPortion;
+ public equals(o: object): boolean {
+ if (!(o instanceof DataCharacter)) {
+ return false;
}
+ const that = o;
+ return this.value === that.value && this.checksumPortion === that.checksumPortion;
+ }
- public hashCode(): number {
- return this.value ^ this.checksumPortion;
- }
+ public hashCode(): number {
+ return this.value ^ this.checksumPortion;
+ }
}
diff --git a/src/core/oned/rss/FinderPattern.ts b/src/core/oned/rss/FinderPattern.ts
index d78b4e7a..e5f2dbda 100644
--- a/src/core/oned/rss/FinderPattern.ts
+++ b/src/core/oned/rss/FinderPattern.ts
@@ -3,37 +3,37 @@ import ResultPoint from '../../ResultPoint';
export default class FinderPattern {
- private resultPoints: Array;
-
- public constructor(private value: number, private startEnd: number[], start: number, end: number, rowNumber: number) {
- this.value = value;
- this.startEnd = startEnd;
- this.resultPoints = new Array();
- this.resultPoints.push(new ResultPoint(start, rowNumber));
- this.resultPoints.push(new ResultPoint(end, rowNumber));
+ private resultPoints: Array;
+
+ public constructor(private value: number, private startEnd: number[], start: number, end: number, rowNumber: number) {
+ this.value = value;
+ this.startEnd = startEnd;
+ this.resultPoints = new Array();
+ this.resultPoints.push(new ResultPoint(start, rowNumber));
+ this.resultPoints.push(new ResultPoint(end, rowNumber));
+ }
+
+ public getValue(): number {
+ return this.value;
+ }
+
+ public getStartEnd(): number[] {
+ return this.startEnd;
+ }
+
+ public getResultPoints(): Array {
+ return this.resultPoints;
+ }
+
+ public equals(o: object): boolean {
+ if (!(o instanceof FinderPattern)) {
+ return false;
}
+ const that = o;
+ return this.value === that.value;
+ }
- public getValue(): number {
- return this.value;
- }
-
- public getStartEnd(): number[] {
- return this.startEnd;
- }
-
- public getResultPoints(): Array {
- return this.resultPoints;
- }
-
- public equals(o: object): boolean {
- if (!(o instanceof FinderPattern)) {
- return false;
- }
- const that = o;
- return this.value === that.value;
- }
-
- public hashCode(): number {
- return this.value;
- }
+ public hashCode(): number {
+ return this.value;
+ }
}
diff --git a/src/core/oned/rss/Pair.ts b/src/core/oned/rss/Pair.ts
index 2aca169c..6ff97a50 100644
--- a/src/core/oned/rss/Pair.ts
+++ b/src/core/oned/rss/Pair.ts
@@ -3,24 +3,24 @@ import FinderPattern from './FinderPattern';
export default class Pair extends DataCharacter {
- private finderPattern: FinderPattern;
- private count: number = 0;
+ private finderPattern: FinderPattern;
+ private count: number = 0;
- public constructor(value: number, checksumPortion: number, finderPattern: FinderPattern) {
- super(value, checksumPortion);
- this.finderPattern = finderPattern;
- }
+ public constructor(value: number, checksumPortion: number, finderPattern: FinderPattern) {
+ super(value, checksumPortion);
+ this.finderPattern = finderPattern;
+ }
- getFinderPattern(): FinderPattern {
- return this.finderPattern;
- }
+ getFinderPattern(): FinderPattern {
+ return this.finderPattern;
+ }
- getCount(): number {
- return this.count;
- }
+ getCount(): number {
+ return this.count;
+ }
- incrementCount() {
- this.count++;
- }
+ incrementCount() {
+ this.count++;
+ }
}
diff --git a/src/core/oned/rss/RSS14Reader.ts b/src/core/oned/rss/RSS14Reader.ts
index 30bd17ab..6d3bb4c1 100644
--- a/src/core/oned/rss/RSS14Reader.ts
+++ b/src/core/oned/rss/RSS14Reader.ts
@@ -17,407 +17,398 @@ import OneDReader from '../OneDReader';
export default class RSS14Reader extends AbstractRSSReader {
- private static readonly OUTSIDE_EVEN_TOTAL_SUBSET: number[] = [1, 10, 34, 70, 126];
- private static readonly INSIDE_ODD_TOTAL_SUBSET: number[] = [4, 20, 48, 81];
- private static readonly OUTSIDE_GSUM: number[] = [0, 161, 961, 2015, 2715];
- private static readonly INSIDE_GSUM: number[] = [0, 336, 1036, 1516];
- private static readonly OUTSIDE_ODD_WIDEST: number[] = [8, 6, 4, 3, 1];
- private static readonly INSIDE_ODD_WIDEST: number[] = [2, 4, 6, 8];
-
- private static readonly FINDER_PATTERNS: Int32Array[] = [
- Int32Array.from([ 3, 8, 2, 1 ]),
- Int32Array.from([ 3, 5, 5, 1 ]),
- Int32Array.from([ 3, 3, 7, 1 ]),
- Int32Array.from([ 3, 1, 9, 1 ]),
- Int32Array.from([ 2, 7, 4, 1 ]),
- Int32Array.from([ 2, 5, 6, 1 ]),
- Int32Array.from([ 2, 3, 8, 1 ]),
- Int32Array.from([ 1, 5, 7, 1 ]),
- Int32Array.from([ 1, 3, 9, 1 ]),
- ];
-
- private readonly possibleLeftPairs: Pair[] = [];
- private readonly possibleRightPairs: Pair[] = [];
-
- public decodeRow(rowNumber: number, row: BitArray, hints?: Map): Result {
- const leftPair = this.decodePair(row, false, rowNumber, hints);
- RSS14Reader.addOrTally(this.possibleLeftPairs, leftPair);
- row.reverse();
- let rightPair = this.decodePair(row, true, rowNumber, hints);
- RSS14Reader.addOrTally(this.possibleRightPairs, rightPair);
- row.reverse();
- for (let left of this.possibleLeftPairs) {
- if (left.getCount() > 1) {
- for (let right of this.possibleRightPairs) {
- if (right.getCount() > 1 && RSS14Reader.checkChecksum(left, right)) {
- return RSS14Reader.constructResult(left, right);
- }
- }
- }
+ private static readonly OUTSIDE_EVEN_TOTAL_SUBSET: number[] = [1, 10, 34, 70, 126];
+ private static readonly INSIDE_ODD_TOTAL_SUBSET: number[] = [4, 20, 48, 81];
+ private static readonly OUTSIDE_GSUM: number[] = [0, 161, 961, 2015, 2715];
+ private static readonly INSIDE_GSUM: number[] = [0, 336, 1036, 1516];
+ private static readonly OUTSIDE_ODD_WIDEST: number[] = [8, 6, 4, 3, 1];
+ private static readonly INSIDE_ODD_WIDEST: number[] = [2, 4, 6, 8];
+
+ private static readonly FINDER_PATTERNS: Int32Array[] = [
+ Int32Array.from([3, 8, 2, 1]),
+ Int32Array.from([3, 5, 5, 1]),
+ Int32Array.from([3, 3, 7, 1]),
+ Int32Array.from([3, 1, 9, 1]),
+ Int32Array.from([2, 7, 4, 1]),
+ Int32Array.from([2, 5, 6, 1]),
+ Int32Array.from([2, 3, 8, 1]),
+ Int32Array.from([1, 5, 7, 1]),
+ Int32Array.from([1, 3, 9, 1]),
+ ];
+
+ private readonly possibleLeftPairs: Pair[] = [];
+ private readonly possibleRightPairs: Pair[] = [];
+
+ public decodeRow(rowNumber: number, row: BitArray, hints?: Map): Result {
+ const leftPair = this.decodePair(row, false, rowNumber, hints);
+ RSS14Reader.addOrTally(this.possibleLeftPairs, leftPair);
+ row.reverse();
+ let rightPair = this.decodePair(row, true, rowNumber, hints);
+ RSS14Reader.addOrTally(this.possibleRightPairs, rightPair);
+ row.reverse();
+ for (let left of this.possibleLeftPairs) {
+ if (left.getCount() > 1) {
+ for (let right of this.possibleRightPairs) {
+ if (right.getCount() > 1 && RSS14Reader.checkChecksum(left, right)) {
+ return RSS14Reader.constructResult(left, right);
+ }
}
- throw new NotFoundException();
+ }
}
+ throw new NotFoundException();
+ }
- private static addOrTally(possiblePairs: Pair[], pair: Pair) {
- if (pair == null) {
- return;
- }
- let found = false;
- for (let other of possiblePairs) {
- if (other.getValue() === pair.getValue()) {
- other.incrementCount();
- found = true;
- break;
- }
- }
- if (!found) {
- possiblePairs.push(pair);
- }
+ private static addOrTally(possiblePairs: Pair[], pair: Pair) {
+ if (pair == null) {
+ return;
}
-
- public reset() {
- this.possibleLeftPairs.length = 0;
- this.possibleRightPairs.length = 0;
+ let found = false;
+ for (let other of possiblePairs) {
+ if (other.getValue() === pair.getValue()) {
+ other.incrementCount();
+ found = true;
+ break;
+ }
}
+ if (!found) {
+ possiblePairs.push(pair);
+ }
+ }
- private static constructResult(leftPair: Pair, rightPair: Pair): Result {
- let symbolValue = 4537077 * leftPair.getValue() + rightPair.getValue();
- let text = new String(symbolValue).toString();
-
- let buffer = new StringBuilder();
- for (let i = 13 - text.length; i > 0; i--) {
- buffer.append('0');
- }
- buffer.append(text);
+ public reset() {
+ this.possibleLeftPairs.length = 0;
+ this.possibleRightPairs.length = 0;
+ }
- let checkDigit = 0;
- for (let i = 0; i < 13; i++) {
- let digit = buffer.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
- checkDigit += ((i & 0x01) === 0) ? 3 * digit : digit;
- }
- checkDigit = 10 - (checkDigit % 10);
- if (checkDigit === 10) {
- checkDigit = 0;
- }
- buffer.append(checkDigit.toString());
+ private static constructResult(leftPair: Pair, rightPair: Pair): Result {
+ let symbolValue = 4537077 * leftPair.getValue() + rightPair.getValue();
+ let text = new String(symbolValue).toString();
- let leftPoints = leftPair.getFinderPattern().getResultPoints();
- let rightPoints = rightPair.getFinderPattern().getResultPoints();
- return new Result(buffer.toString(), null, 0, [leftPoints[0], leftPoints[1], rightPoints[0], rightPoints[1]], BarcodeFormat.RSS_14, new Date().getTime());
+ let buffer = new StringBuilder();
+ for (let i = 13 - text.length; i > 0; i--) {
+ buffer.append('0');
}
+ buffer.append(text);
- private static checkChecksum(leftPair: Pair, rightPair: Pair): boolean {
- let checkValue = (leftPair.getChecksumPortion() + 16 * rightPair.getChecksumPortion()) % 79;
- let targetCheckValue =
- 9 * leftPair.getFinderPattern().getValue() + rightPair.getFinderPattern().getValue();
- if (targetCheckValue > 72) {
- targetCheckValue--;
- }
- if (targetCheckValue > 8) {
- targetCheckValue--;
- }
- return checkValue === targetCheckValue;
+ let checkDigit = 0;
+ for (let i = 0; i < 13; i++) {
+ let digit = buffer.charAt(i).charCodeAt(0) - '0'.charCodeAt(0);
+ checkDigit += ((i & 0x01) === 0) ? 3 * digit : digit;
}
-
- private decodePair(row: BitArray, right: boolean, rowNumber: number, hints: Map): Pair {
- try {
- let startEnd = this.findFinderPattern(row, right);
- let pattern = this.parseFoundFinderPattern(row, rowNumber, right, startEnd);
-
- let resultPointCallback = hints == null ? null : hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
-
- if (resultPointCallback != null) {
- let center = (startEnd[0] + startEnd[1]) / 2.0;
- if (right) {
- // row is actually reversed
- center = row.getSize() - 1 - center;
- }
- resultPointCallback.foundPossibleResultPoint(new ResultPoint(center, rowNumber));
- }
-
- let outside = this.decodeDataCharacter(row, pattern, true);
- let inside = this.decodeDataCharacter(row, pattern, false);
- return new Pair(1597 * outside.getValue() + inside.getValue(),
- outside.getChecksumPortion() + 4 * inside.getChecksumPortion(),
- pattern);
- }
- catch (err) {
- return null;
- }
+ checkDigit = 10 - (checkDigit % 10);
+ if (checkDigit === 10) {
+ checkDigit = 0;
+ }
+ buffer.append(checkDigit.toString());
+
+ let leftPoints = leftPair.getFinderPattern().getResultPoints();
+ let rightPoints = rightPair.getFinderPattern().getResultPoints();
+ return new Result(buffer.toString(), null, 0, [leftPoints[0], leftPoints[1], rightPoints[0], rightPoints[1]], BarcodeFormat.RSS_14, new Date().getTime());
+ }
+
+ private static checkChecksum(leftPair: Pair, rightPair: Pair): boolean {
+ let checkValue = (leftPair.getChecksumPortion() + 16 * rightPair.getChecksumPortion()) % 79;
+ let targetCheckValue =
+ 9 * leftPair.getFinderPattern().getValue() + rightPair.getFinderPattern().getValue();
+ if (targetCheckValue > 72) {
+ targetCheckValue--;
}
+ if (targetCheckValue > 8) {
+ targetCheckValue--;
+ }
+ return checkValue === targetCheckValue;
+ }
- private decodeDataCharacter(row: BitArray, pattern: FinderPattern, outsideChar: boolean): DataCharacter {
+ private decodePair(row: BitArray, right: boolean, rowNumber: number, hints: Map): Pair {
+ try {
+ let startEnd = this.findFinderPattern(row, right);
+ let pattern = this.parseFoundFinderPattern(row, rowNumber, right, startEnd);
- let counters = this.getDataCharacterCounters();
- for (let x = 0; x < counters.length; x++) {
- counters[x] = 0;
- }
+ let resultPointCallback = hints == null ? null : hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
- if (outsideChar) {
- OneDReader.recordPatternInReverse(row, pattern.getStartEnd()[0], counters);
- } else {
- OneDReader.recordPattern(row, pattern.getStartEnd()[1] + 1, counters);
- // reverse it
- for (let i = 0, j = counters.length - 1; i < j; i++ , j--) {
- let temp = counters[i];
- counters[i] = counters[j];
- counters[j] = temp;
- }
+ if (resultPointCallback != null) {
+ let center = (startEnd[0] + startEnd[1]) / 2.0;
+ if (right) {
+ // row is actually reversed
+ center = row.getSize() - 1 - center;
}
+ resultPointCallback.foundPossibleResultPoint(new ResultPoint(center, rowNumber));
+ }
+
+ let outside = this.decodeDataCharacter(row, pattern, true);
+ let inside = this.decodeDataCharacter(row, pattern, false);
+ return new Pair(1597 * outside.getValue() + inside.getValue(),
+ outside.getChecksumPortion() + 4 * inside.getChecksumPortion(),
+ pattern);
+ } catch (err) {
+ return null;
+ }
+ }
- let numModules = outsideChar ? 16 : 15;
- let elementWidth = MathUtils.sum(new Int32Array(counters)) / numModules;
-
- let oddCounts = this.getOddCounts();
- let evenCounts = this.getEvenCounts();
- let oddRoundingErrors = this.getOddRoundingErrors();
- let evenRoundingErrors = this.getEvenRoundingErrors();
-
- for (let i = 0; i < counters.length; i++) {
- let value = counters[i] / elementWidth;
- let count = Math.floor(value + 0.5);
- if (count < 1) {
- count = 1;
- } else if (count > 8) {
- count = 8;
- }
- let offset = Math.floor(i / 2);
- if ((i & 0x01) === 0) {
- oddCounts[offset] = count;
- oddRoundingErrors[offset] = value - count;
- } else {
- evenCounts[offset] = count;
- evenRoundingErrors[offset] = value - count;
- }
- }
+ private decodeDataCharacter(row: BitArray, pattern: FinderPattern, outsideChar: boolean): DataCharacter {
- this.adjustOddEvenCounts(outsideChar, numModules);
+ let counters = this.getDataCharacterCounters();
+ for (let x = 0; x < counters.length; x++) {
+ counters[x] = 0;
+ }
- let oddSum = 0;
- let oddChecksumPortion = 0;
- for (let i = oddCounts.length - 1; i >= 0; i--) {
- oddChecksumPortion *= 9;
- oddChecksumPortion += oddCounts[i];
- oddSum += oddCounts[i];
- }
- let evenChecksumPortion = 0;
- let evenSum = 0;
- for (let i = evenCounts.length - 1; i >= 0; i--) {
- evenChecksumPortion *= 9;
- evenChecksumPortion += evenCounts[i];
- evenSum += evenCounts[i];
- }
- let checksumPortion = oddChecksumPortion + 3 * evenChecksumPortion;
-
- if (outsideChar) {
- if ((oddSum & 0x01) !== 0 || oddSum > 12 || oddSum < 4) {
- throw new NotFoundException();
- }
- let group = (12 - oddSum) / 2;
- let oddWidest = RSS14Reader.OUTSIDE_ODD_WIDEST[group];
- let evenWidest = 9 - oddWidest;
- let vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, false);
- let vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, true);
- let tEven = RSS14Reader.OUTSIDE_EVEN_TOTAL_SUBSET[group];
- let gSum = RSS14Reader.OUTSIDE_GSUM[group];
- return new DataCharacter(vOdd * tEven + vEven + gSum, checksumPortion);
- } else {
- if ((evenSum & 0x01) !== 0 || evenSum > 10 || evenSum < 4) {
- throw new NotFoundException();
- }
- let group = (10 - evenSum) / 2;
- let oddWidest = RSS14Reader.INSIDE_ODD_WIDEST[group];
- let evenWidest = 9 - oddWidest;
- let vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, true);
- let vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, false);
- let tOdd = RSS14Reader.INSIDE_ODD_TOTAL_SUBSET[group];
- let gSum = RSS14Reader.INSIDE_GSUM[group];
- return new DataCharacter(vEven * tOdd + vOdd + gSum, checksumPortion);
- }
+ if (outsideChar) {
+ OneDReader.recordPatternInReverse(row, pattern.getStartEnd()[0], counters);
+ } else {
+ OneDReader.recordPattern(row, pattern.getStartEnd()[1] + 1, counters);
+ // reverse it
+ for (let i = 0, j = counters.length - 1; i < j; i++, j--) {
+ let temp = counters[i];
+ counters[i] = counters[j];
+ counters[j] = temp;
+ }
+ }
+ let numModules = outsideChar ? 16 : 15;
+ let elementWidth = MathUtils.sum(new Int32Array(counters)) / numModules;
+
+ let oddCounts = this.getOddCounts();
+ let evenCounts = this.getEvenCounts();
+ let oddRoundingErrors = this.getOddRoundingErrors();
+ let evenRoundingErrors = this.getEvenRoundingErrors();
+
+ for (let i = 0; i < counters.length; i++) {
+ let value = counters[i] / elementWidth;
+ let count = Math.floor(value + 0.5);
+ if (count < 1) {
+ count = 1;
+ } else if (count > 8) {
+ count = 8;
+ }
+ let offset = Math.floor(i / 2);
+ if ((i & 0x01) === 0) {
+ oddCounts[offset] = count;
+ oddRoundingErrors[offset] = value - count;
+ } else {
+ evenCounts[offset] = count;
+ evenRoundingErrors[offset] = value - count;
+ }
}
- private findFinderPattern(row: BitArray, rightFinderPattern: boolean): number[] {
-
- let counters = this.getDecodeFinderCounters();
- counters[0] = 0;
- counters[1] = 0;
- counters[2] = 0;
- counters[3] = 0;
-
- let width = row.getSize();
- let isWhite = false;
- let rowOffset = 0;
- while (rowOffset < width) {
- isWhite = !row.get(rowOffset);
- if (rightFinderPattern === isWhite) {
- // Will encounter white first when searching for right finder pattern
- break;
- }
- rowOffset++;
- }
+ this.adjustOddEvenCounts(outsideChar, numModules);
- let counterPosition = 0;
- let patternStart = rowOffset;
- for (let x = rowOffset; x < width; x++) {
- if (row.get(x) !== isWhite) {
- counters[counterPosition]++;
- } else {
- if (counterPosition === 3) {
- if (AbstractRSSReader.isFinderPattern(counters)) {
- return [patternStart, x ];
- }
- patternStart += counters[0] + counters[1];
- counters[0] = counters[2];
- counters[1] = counters[3];
- counters[2] = 0;
- counters[3] = 0;
- counterPosition--;
- } else {
- counterPosition++;
- }
- counters[counterPosition] = 1;
- isWhite = !isWhite;
- }
- }
- throw new NotFoundException();
+ let oddSum = 0;
+ let oddChecksumPortion = 0;
+ for (let i = oddCounts.length - 1; i >= 0; i--) {
+ oddChecksumPortion *= 9;
+ oddChecksumPortion += oddCounts[i];
+ oddSum += oddCounts[i];
}
+ let evenChecksumPortion = 0;
+ let evenSum = 0;
+ for (let i = evenCounts.length - 1; i >= 0; i--) {
+ evenChecksumPortion *= 9;
+ evenChecksumPortion += evenCounts[i];
+ evenSum += evenCounts[i];
+ }
+ let checksumPortion = oddChecksumPortion + 3 * evenChecksumPortion;
- private parseFoundFinderPattern(row: BitArray, rowNumber: number, right: boolean, startEnd: number[]): FinderPattern {
- // Actually we found elements 2-5
- let firstIsBlack = row.get(startEnd[0]);
- let firstElementStart = startEnd[0] - 1;
- // Locate element 1
- while (firstElementStart >= 0 && firstIsBlack !== row.get(firstElementStart)) {
- firstElementStart--;
- }
- firstElementStart++;
- const firstCounter = startEnd[0] - firstElementStart;
- // Make 'counters' hold 1-4
- const counters = this.getDecodeFinderCounters();
- const copy = new Int32Array(counters.length);
- System.arraycopy(counters, 0, copy, 1, counters.length - 1);
- copy[0] = firstCounter;
- const value = this.parseFinderValue(copy, RSS14Reader.FINDER_PATTERNS);
- let start = firstElementStart;
- let end = startEnd[1];
- if (right) {
- // row is actually reversed
- start = row.getSize() - 1 - start;
- end = row.getSize() - 1 - end;
- }
- return new FinderPattern(value, [ firstElementStart, startEnd[1] ], start, end, rowNumber);
+ if (outsideChar) {
+ if ((oddSum & 0x01) !== 0 || oddSum > 12 || oddSum < 4) {
+ throw new NotFoundException();
+ }
+ let group = (12 - oddSum) / 2;
+ let oddWidest = RSS14Reader.OUTSIDE_ODD_WIDEST[group];
+ let evenWidest = 9 - oddWidest;
+ let vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, false);
+ let vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, true);
+ let tEven = RSS14Reader.OUTSIDE_EVEN_TOTAL_SUBSET[group];
+ let gSum = RSS14Reader.OUTSIDE_GSUM[group];
+ return new DataCharacter(vOdd * tEven + vEven + gSum, checksumPortion);
+ } else {
+ if ((evenSum & 0x01) !== 0 || evenSum > 10 || evenSum < 4) {
+ throw new NotFoundException();
+ }
+ let group = (10 - evenSum) / 2;
+ let oddWidest = RSS14Reader.INSIDE_ODD_WIDEST[group];
+ let evenWidest = 9 - oddWidest;
+ let vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, true);
+ let vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, false);
+ let tOdd = RSS14Reader.INSIDE_ODD_TOTAL_SUBSET[group];
+ let gSum = RSS14Reader.INSIDE_GSUM[group];
+ return new DataCharacter(vEven * tOdd + vOdd + gSum, checksumPortion);
}
- private adjustOddEvenCounts(outsideChar: boolean, numModules: number) {
-
- let oddSum = MathUtils.sum(new Int32Array(this.getOddCounts()));
- let evenSum = MathUtils.sum(new Int32Array(this.getEvenCounts()));
-
- let incrementOdd = false;
- let decrementOdd = false;
- let incrementEven = false;
- let decrementEven = false;
-
- if (outsideChar) {
- if (oddSum > 12) {
- decrementOdd = true;
- }
- else if (oddSum < 4) {
- incrementOdd = true;
- }
- if (evenSum > 12) {
- decrementEven = true;
- }
- else if (evenSum < 4) {
- incrementEven = true;
- }
- }
- else {
- if (oddSum > 11) {
- decrementOdd = true;
- }
- else if (oddSum < 5) {
- incrementOdd = true;
- }
- if (evenSum > 10) {
- decrementEven = true;
- }
- else if (evenSum < 4) {
- incrementEven = true;
- }
- }
+ }
+
+ private findFinderPattern(row: BitArray, rightFinderPattern: boolean): number[] {
+
+ let counters = this.getDecodeFinderCounters();
+ counters[0] = 0;
+ counters[1] = 0;
+ counters[2] = 0;
+ counters[3] = 0;
+
+ let width = row.getSize();
+ let isWhite = false;
+ let rowOffset = 0;
+ while (rowOffset < width) {
+ isWhite = !row.get(rowOffset);
+ if (rightFinderPattern === isWhite) {
+ // Will encounter white first when searching for right finder pattern
+ break;
+ }
+ rowOffset++;
+ }
- let mismatch = oddSum + evenSum - numModules;
- let oddParityBad = (oddSum & 0x01) === (outsideChar ? 1 : 0);
- let evenParityBad = (evenSum & 0x01) === 1;
- if (mismatch === 1) {
- if (oddParityBad) {
- if (evenParityBad) {
- throw new NotFoundException();
- }
- decrementOdd = true;
+ let counterPosition = 0;
+ let patternStart = rowOffset;
+ for (let x = rowOffset; x < width; x++) {
+ if (row.get(x) !== isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (counterPosition === 3) {
+ if (AbstractRSSReader.isFinderPattern(counters)) {
+ return [patternStart, x];
+ }
+ patternStart += counters[0] + counters[1];
+ counters[0] = counters[2];
+ counters[1] = counters[3];
+ counters[2] = 0;
+ counters[3] = 0;
+ counterPosition--;
} else {
- if (!evenParityBad) {
- throw new NotFoundException();
- }
- decrementEven = true;
+ counterPosition++;
}
- } else if (mismatch === -1) {
- if (oddParityBad) {
- if (evenParityBad) {
- throw new NotFoundException();
- }
- incrementOdd = true;
- } else {
- if (!evenParityBad) {
- throw new NotFoundException();
- }
- incrementEven = true;
- }
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+ throw new NotFoundException();
+ }
+
+ private parseFoundFinderPattern(row: BitArray, rowNumber: number, right: boolean, startEnd: number[]): FinderPattern {
+ // Actually we found elements 2-5
+ let firstIsBlack = row.get(startEnd[0]);
+ let firstElementStart = startEnd[0] - 1;
+ // Locate element 1
+ while (firstElementStart >= 0 && firstIsBlack !== row.get(firstElementStart)) {
+ firstElementStart--;
+ }
+ firstElementStart++;
+ const firstCounter = startEnd[0] - firstElementStart;
+ // Make 'counters' hold 1-4
+ const counters = this.getDecodeFinderCounters();
+ const copy = new Int32Array(counters.length);
+ System.arraycopy(counters, 0, copy, 1, counters.length - 1);
+ copy[0] = firstCounter;
+ const value = this.parseFinderValue(copy, RSS14Reader.FINDER_PATTERNS);
+ let start = firstElementStart;
+ let end = startEnd[1];
+ if (right) {
+ // row is actually reversed
+ start = row.getSize() - 1 - start;
+ end = row.getSize() - 1 - end;
+ }
+ return new FinderPattern(value, [firstElementStart, startEnd[1]], start, end, rowNumber);
+ }
+
+ private adjustOddEvenCounts(outsideChar: boolean, numModules: number) {
+
+ let oddSum = MathUtils.sum(new Int32Array(this.getOddCounts()));
+ let evenSum = MathUtils.sum(new Int32Array(this.getEvenCounts()));
+
+ let incrementOdd = false;
+ let decrementOdd = false;
+ let incrementEven = false;
+ let decrementEven = false;
+
+ if (outsideChar) {
+ if (oddSum > 12) {
+ decrementOdd = true;
+ } else if (oddSum < 4) {
+ incrementOdd = true;
+ }
+ if (evenSum > 12) {
+ decrementEven = true;
+ } else if (evenSum < 4) {
+ incrementEven = true;
+ }
+ } else {
+ if (oddSum > 11) {
+ decrementOdd = true;
+ } else if (oddSum < 5) {
+ incrementOdd = true;
+ }
+ if (evenSum > 10) {
+ decrementEven = true;
+ } else if (evenSum < 4) {
+ incrementEven = true;
+ }
+ }
+
+ let mismatch = oddSum + evenSum - numModules;
+ let oddParityBad = (oddSum & 0x01) === (outsideChar ? 1 : 0);
+ let evenParityBad = (evenSum & 0x01) === 1;
+ if (mismatch === 1) {
+ if (oddParityBad) {
+ if (evenParityBad) {
+ throw new NotFoundException();
}
- else if (mismatch === 0) {
- if (oddParityBad) {
- if (!evenParityBad) {
- throw new NotFoundException();
- }
- // Both bad
- if (oddSum < evenSum) {
- incrementOdd = true;
- decrementEven = true;
- } else {
- decrementOdd = true;
- incrementEven = true;
- }
- }
- else {
- if (evenParityBad) {
- throw new NotFoundException();
- }
- // Nothing to do!
- }
+ decrementOdd = true;
+ } else {
+ if (!evenParityBad) {
+ throw new NotFoundException();
}
- else {
- throw new NotFoundException();
+ decrementEven = true;
+ }
+ } else if (mismatch === -1) {
+ if (oddParityBad) {
+ if (evenParityBad) {
+ throw new NotFoundException();
}
-
- if (incrementOdd) {
- if (decrementOdd) {
- throw new NotFoundException();
- }
- AbstractRSSReader.increment(this.getOddCounts(), this.getOddRoundingErrors());
+ incrementOdd = true;
+ } else {
+ if (!evenParityBad) {
+ throw new NotFoundException();
}
- if (decrementOdd) {
- AbstractRSSReader.decrement(this.getOddCounts(), this.getOddRoundingErrors());
+ incrementEven = true;
+ }
+ } else if (mismatch === 0) {
+ if (oddParityBad) {
+ if (!evenParityBad) {
+ throw new NotFoundException();
}
- if (incrementEven) {
- if (decrementEven) {
- throw new NotFoundException();
- }
- AbstractRSSReader.increment(this.getEvenCounts(), this.getOddRoundingErrors());
+ // Both bad
+ if (oddSum < evenSum) {
+ incrementOdd = true;
+ decrementEven = true;
+ } else {
+ decrementOdd = true;
+ incrementEven = true;
}
- if (decrementEven) {
- AbstractRSSReader.decrement(this.getEvenCounts(), this.getEvenRoundingErrors());
+ } else {
+ if (evenParityBad) {
+ throw new NotFoundException();
}
+ // Nothing to do!
+ }
+ } else {
+ throw new NotFoundException();
+ }
+
+ if (incrementOdd) {
+ if (decrementOdd) {
+ throw new NotFoundException();
+ }
+ AbstractRSSReader.increment(this.getOddCounts(), this.getOddRoundingErrors());
+ }
+ if (decrementOdd) {
+ AbstractRSSReader.decrement(this.getOddCounts(), this.getOddRoundingErrors());
+ }
+ if (incrementEven) {
+ if (decrementEven) {
+ throw new NotFoundException();
+ }
+ AbstractRSSReader.increment(this.getEvenCounts(), this.getOddRoundingErrors());
+ }
+ if (decrementEven) {
+ AbstractRSSReader.decrement(this.getEvenCounts(), this.getEvenRoundingErrors());
}
+ }
}
diff --git a/src/core/oned/rss/RSSUtils.ts b/src/core/oned/rss/RSSUtils.ts
index 78d3d3ea..cec43b7f 100644
--- a/src/core/oned/rss/RSSUtils.ts
+++ b/src/core/oned/rss/RSSUtils.ts
@@ -15,7 +15,7 @@ export default class RSSUtils {
let elements = widths.length;
for (let bar = 0; bar < elements - 1; bar++) {
let elmWidth;
- for (elmWidth = 1, narrowMask |= 1 << bar; elmWidth < widths[bar]; elmWidth++ , narrowMask &= ~(1 << bar)) {
+ for (elmWidth = 1, narrowMask |= 1 << bar; elmWidth < widths[bar]; elmWidth++, narrowMask &= ~(1 << bar)) {
let subVal = RSSUtils.combins(n - elmWidth - 1, elements - bar - 2);
if (noNarrow && (narrowMask === 0) && (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {
subVal -= RSSUtils.combins(n - elmWidth - (elements - bar), elements - bar - 2);
diff --git a/src/core/oned/rss/expanded/BitArrayBuilder.ts b/src/core/oned/rss/expanded/BitArrayBuilder.ts
index d3dac0c2..545e654f 100644
--- a/src/core/oned/rss/expanded/BitArrayBuilder.ts
+++ b/src/core/oned/rss/expanded/BitArrayBuilder.ts
@@ -17,7 +17,7 @@ export default class BitArrayBuilder {
let firstPair: ExpandedPair = pairs[0];
let firstValue = firstPair.getRightChar().getValue();
for (let i = 11; i >= 0; --i) {
- if ((firstValue & (1 << i)) != 0) {
+ if ((firstValue & (1 << i)) !== 0) {
binary.set(accPos);
}
accPos++;
@@ -28,7 +28,7 @@ export default class BitArrayBuilder {
let leftValue = currentPair.getLeftChar().getValue();
for (let j = 11; j >= 0; --j) {
- if ((leftValue & (1 << j)) != 0) {
+ if ((leftValue & (1 << j)) !== 0) {
binary.set(accPos);
}
accPos++;
@@ -37,7 +37,7 @@ export default class BitArrayBuilder {
if (currentPair.getRightChar() != null) {
let rightValue = currentPair.getRightChar().getValue();
for (let j = 11; j >= 0; --j) {
- if ((rightValue & (1 << j)) != 0) {
+ if ((rightValue & (1 << j)) !== 0) {
binary.set(accPos);
}
accPos++;
diff --git a/src/core/oned/rss/expanded/ExpandedRow.ts b/src/core/oned/rss/expanded/ExpandedRow.ts
index d1c7d7ee..89f2f54a 100644
--- a/src/core/oned/rss/expanded/ExpandedRow.ts
+++ b/src/core/oned/rss/expanded/ExpandedRow.ts
@@ -36,7 +36,7 @@ export default class ExpandedRow {
/**
* Two rows are equal if they contain the same pairs in the same order.
- */
+ */
// @Override
// check implementation
public equals(o1: ExpandedRow, o2: ExpandedRow): boolean {
diff --git a/src/core/oned/rss/expanded/RSSExpandedReader.ts b/src/core/oned/rss/expanded/RSSExpandedReader.ts
index 1ccc4cd6..368c77e2 100644
--- a/src/core/oned/rss/expanded/RSSExpandedReader.ts
+++ b/src/core/oned/rss/expanded/RSSExpandedReader.ts
@@ -32,7 +32,7 @@ export default class RSSExpandedReader extends AbstractRSSReader {
private static readonly EVEN_TOTAL_SUBSET = [4, 20, 52, 104, 204];
private static readonly GSUM = [0, 348, 1388, 2948, 3988];
- private static readonly FINDER_PATTERNS = [
+ private static readonly FINDER_PATTERNS = [
Int32Array.from([1, 8, 4, 1]), // A
Int32Array.from([3, 6, 4, 1]), // B
Int32Array.from([3, 4, 6, 1]), // C
@@ -237,7 +237,7 @@ export default class RSSExpandedReader extends AbstractRSSReader {
let stop = true;
for (let j = 0; j < pairs.length; j++) {
- if (pairs[j].getFinderPattern().getValue() != sequence[j]) {
+ if (pairs[j].getFinderPattern().getValue() !== sequence[j]) {
stop = false;
break;
}
@@ -407,7 +407,7 @@ export default class RSSExpandedReader extends AbstractRSSReader {
let checkCharacterValue = 211 * (s - 4) + checksum;
- return checkCharacterValue == checkCharacter.getValue();
+ return checkCharacterValue === checkCharacter.getValue();
}
private static getNextSecondBar(row: BitArray, initialPos: number): number {
@@ -424,7 +424,7 @@ export default class RSSExpandedReader extends AbstractRSSReader {
// not private for testing
retrieveNextPair(row: BitArray, previousPairs: Array, rowNumber: number): ExpandedPair {
- let isOddPattern = previousPairs.length % 2 == 0;
+ let isOddPattern = previousPairs.length % 2 === 0;
if (this.startFromEven) {
isOddPattern = !isOddPattern;
}
@@ -485,7 +485,7 @@ export default class RSSExpandedReader extends AbstractRSSReader {
let lastPair = previousPairs[previousPairs.length - 1];
rowOffset = lastPair.getFinderPattern().getStartEnd()[1];
}
- let searchingEvenPair = previousPairs.length % 2 != 0;
+ let searchingEvenPair = previousPairs.length % 2 !== 0;
if (this.startFromEven) {
searchingEvenPair = !searchingEvenPair;
}
@@ -502,10 +502,10 @@ export default class RSSExpandedReader extends AbstractRSSReader {
let counterPosition = 0;
let patternStart = rowOffset;
for (let x = rowOffset; x < width; x++) {
- if (row.get(x) != isWhite) {
+ if (row.get(x) !== isWhite) {
counters[counterPosition]++;
} else {
- if (counterPosition == 3) {
+ if (counterPosition === 3) {
if (searchingEvenPair) {
RSSExpandedReader.reverseCounters(counters);
}
@@ -601,7 +601,7 @@ export default class RSSExpandedReader extends AbstractRSSReader {
} else {
RSSExpandedReader.recordPattern(row, pattern.getStartEnd()[1], counters);
// reverse it
- for (let i = 0, j = counters.length - 1; i < j; i++ , j--) {
+ for (let i = 0, j = counters.length - 1; i < j; i++, j--) {
let temp = counters[i];
counters[i] = counters[j];
counters[j] = temp;
@@ -637,7 +637,7 @@ export default class RSSExpandedReader extends AbstractRSSReader {
count = 8;
}
let offset = i / 2;
- if ((i & 0x01) == 0) {
+ if ((i & 0x01) === 0) {
oddCounts[offset] = count;
oddRoundingErrors[offset] = value - count;
} else {
@@ -670,7 +670,7 @@ export default class RSSExpandedReader extends AbstractRSSReader {
}
let checksumPortion = oddChecksumPortion + evenChecksumPortion;
- if ((oddSum & 0x01) != 0 || oddSum > 13 || oddSum < 4) {
+ if ((oddSum & 0x01) !== 0 || oddSum > 13 || oddSum < 4) {
throw new NotFoundException();
}
@@ -688,7 +688,7 @@ export default class RSSExpandedReader extends AbstractRSSReader {
private static isNotA1left(pattern: FinderPattern, isOddPattern: boolean, leftChar: boolean): boolean {
// A1: pattern.getValue is 0 (A), and it's an oddPattern, and it is a left char
- return !(pattern.getValue() == 0 && isOddPattern && leftChar);
+ return !(pattern.getValue() === 0 && isOddPattern && leftChar);
}
private adjustOddEvenCounts(numModules) {
@@ -713,9 +713,9 @@ export default class RSSExpandedReader extends AbstractRSSReader {
}
let mismatch = oddSum + evenSum - numModules;
- let oddParityBad = (oddSum & 0x01) == 1;
- let evenParityBad = (evenSum & 0x01) == 0;
- if (mismatch == 1) {
+ let oddParityBad = (oddSum & 0x01) === 1;
+ let evenParityBad = (evenSum & 0x01) === 0;
+ if (mismatch === 1) {
if (oddParityBad) {
if (evenParityBad) {
throw new NotFoundException();
@@ -727,7 +727,7 @@ export default class RSSExpandedReader extends AbstractRSSReader {
}
decrementEven = true;
}
- } else if (mismatch == -1) {
+ } else if (mismatch === -1) {
if (oddParityBad) {
if (evenParityBad) {
throw new NotFoundException();
@@ -739,7 +739,7 @@ export default class RSSExpandedReader extends AbstractRSSReader {
}
incrementEven = true;
}
- } else if (mismatch == 0) {
+ } else if (mismatch === 0) {
if (oddParityBad) {
if (!evenParityBad) {
throw new NotFoundException();
diff --git a/src/core/oned/rss/expanded/decoders/AI01393xDecoder.ts b/src/core/oned/rss/expanded/decoders/AI01393xDecoder.ts
index 0120e23f..b2ef01e6 100644
--- a/src/core/oned/rss/expanded/decoders/AI01393xDecoder.ts
+++ b/src/core/oned/rss/expanded/decoders/AI01393xDecoder.ts
@@ -28,10 +28,10 @@ export default class AI01393xDecoder extends AI01decoder {
buf.append(')');
let firstThreeDigits = this.getGeneralDecoder().extractNumericValueFromBitArray(AI01393xDecoder.HEADER_SIZE + AI01decoder.GTIN_SIZE + AI01393xDecoder.LAST_DIGIT_SIZE, AI01393xDecoder.FIRST_THREE_DIGITS_SIZE);
- if (firstThreeDigits / 100 == 0) {
+ if (firstThreeDigits / 100 === 0) {
buf.append('0');
}
- if (firstThreeDigits / 10 == 0) {
+ if (firstThreeDigits / 10 === 0) {
buf.append('0');
}
buf.append(firstThreeDigits);
diff --git a/src/core/oned/rss/expanded/decoders/AI013x0x1xDecoder.ts b/src/core/oned/rss/expanded/decoders/AI013x0x1xDecoder.ts
index 581d9056..056fd405 100644
--- a/src/core/oned/rss/expanded/decoders/AI013x0x1xDecoder.ts
+++ b/src/core/oned/rss/expanded/decoders/AI013x0x1xDecoder.ts
@@ -18,7 +18,7 @@ export default class AI013x0x1xDecoder extends AI01weightDecoder {
}
public parseInformation(): string {
- if (this.getInformation().getSize() != AI013x0x1xDecoder.HEADER_SIZE + AI013x0x1xDecoder.GTIN_SIZE + AI013x0x1xDecoder.WEIGHT_SIZE + AI013x0x1xDecoder.DATE_SIZE) {
+ if (this.getInformation().getSize() !== AI013x0x1xDecoder.HEADER_SIZE + AI013x0x1xDecoder.GTIN_SIZE + AI013x0x1xDecoder.WEIGHT_SIZE + AI013x0x1xDecoder.DATE_SIZE) {
throw new NotFoundException();
}
@@ -33,7 +33,7 @@ export default class AI013x0x1xDecoder extends AI01weightDecoder {
private encodeCompressedDate(buf: StringBuilder, currentPos: number): void {
let numericDate = this.getGeneralDecoder().extractNumericValueFromBitArray(currentPos, AI013x0x1xDecoder.DATE_SIZE);
- if (numericDate == 38400) {
+ if (numericDate === 38400) {
return;
}
@@ -47,15 +47,15 @@ export default class AI013x0x1xDecoder extends AI01weightDecoder {
numericDate /= 12;
let year = numericDate;
- if (year / 10 == 0) {
+ if (year / 10 === 0) {
buf.append('0');
}
buf.append(year);
- if (month / 10 == 0) {
+ if (month / 10 === 0) {
buf.append('0');
}
buf.append(month);
- if (day / 10 == 0) {
+ if (day / 10 === 0) {
buf.append('0');
}
buf.append(day);
diff --git a/src/core/oned/rss/expanded/decoders/AI013x0xDecoder.ts b/src/core/oned/rss/expanded/decoders/AI013x0xDecoder.ts
index 631a6d72..10df69e8 100644
--- a/src/core/oned/rss/expanded/decoders/AI013x0xDecoder.ts
+++ b/src/core/oned/rss/expanded/decoders/AI013x0xDecoder.ts
@@ -12,7 +12,7 @@ export default abstract class AI013x0xDecoder extends AI01weightDecoder {
}
public parseInformation() {
- if (this.getInformation().getSize() != AI013x0xDecoder.HEADER_SIZE + AI01weightDecoder.GTIN_SIZE + AI013x0xDecoder.WEIGHT_SIZE) {
+ if (this.getInformation().getSize() !== AI013x0xDecoder.HEADER_SIZE + AI01weightDecoder.GTIN_SIZE + AI013x0xDecoder.WEIGHT_SIZE) {
throw new NotFoundException();
}
diff --git a/src/core/oned/rss/expanded/decoders/BlockParsedResult.ts b/src/core/oned/rss/expanded/decoders/BlockParsedResult.ts
index 669cbb77..a6ade430 100644
--- a/src/core/oned/rss/expanded/decoders/BlockParsedResult.ts
+++ b/src/core/oned/rss/expanded/decoders/BlockParsedResult.ts
@@ -22,4 +22,4 @@ export default class BlockParsedResult {
return this.finished;
}
-}
\ No newline at end of file
+}
diff --git a/src/core/oned/rss/expanded/decoders/createDecoder.ts b/src/core/oned/rss/expanded/decoders/createDecoder.ts
index 2c0efc4c..27965777 100644
--- a/src/core/oned/rss/expanded/decoders/createDecoder.ts
+++ b/src/core/oned/rss/expanded/decoders/createDecoder.ts
@@ -1,4 +1,5 @@
-import { BitArray, IllegalStateException } from '../../../../..';
+import BitArray from '../../../../common/BitArray';
+import IllegalStateException from '../../../../IllegalStateException';
import AbstractExpandedDecoder from './AbstractExpandedDecoder';
import AI013103decoder from './AI013103decoder';
import AI01320xDecoder from './AI01320xDecoder';
diff --git a/src/core/pdf417/PDF417Common.ts b/src/core/pdf417/PDF417Common.ts
index a083b4c0..48294b36 100644
--- a/src/core/pdf417/PDF417Common.ts
+++ b/src/core/pdf417/PDF417Common.ts
@@ -28,440 +28,440 @@ import { int } from '../../customTypings';
* @author SITA Lab (kevin.osullivan@sita.aero)
* @author Guenther Grau
*/
-export default /*public final*/ class PDF417Common {
+export default /* public final */ class PDF417Common {
- public static /*final int*/ NUMBER_OF_CODEWORDS = 929;
- // Maximum Codewords (Data + Error).
- public static /*final int*/ MAX_CODEWORDS_IN_BARCODE = PDF417Common.NUMBER_OF_CODEWORDS - 1;
- public static /*final int*/ MIN_ROWS_IN_BARCODE = 3;
- public static /*final int*/ MAX_ROWS_IN_BARCODE = 90;
- // One left row indication column + max 30 data columns + one right row indicator column
- // public static /*final*/ MAX_CODEWORDS_IN_ROW: /*int*/ number = 32;
- public static /*final int*/ MODULES_IN_CODEWORD = 17;
- public static /*final int*/ MODULES_IN_STOP_PATTERN = 18;
- public static /*final int*/ BARS_IN_MODULE = 8;
+ public static /* final int */ NUMBER_OF_CODEWORDS = 929;
+ // Maximum Codewords (Data + Error).
+ public static /* final int */ MAX_CODEWORDS_IN_BARCODE = PDF417Common.NUMBER_OF_CODEWORDS - 1;
+ public static /* final int */ MIN_ROWS_IN_BARCODE = 3;
+ public static /* final int */ MAX_ROWS_IN_BARCODE = 90;
+ // One left row indication column + max 30 data columns + one right row indicator column
+ // public static /*final */ MAX_CODEWORDS_IN_ROW: /*int */ number = 32;
+ public static /* final int */ MODULES_IN_CODEWORD = 17;
+ public static /* final int */ MODULES_IN_STOP_PATTERN = 18;
+ public static /* final int */ BARS_IN_MODULE = 8;
- private static /*final int[]*/ EMPTY_INT_ARRAY: Int32Array = new Int32Array([]);
+ private static /* final int[] */ EMPTY_INT_ARRAY: Int32Array = new Int32Array([]);
- private PDF417Common() {
- }
+ private PDF417Common() {
+ }
- /**
- * @param moduleBitCount values to sum
- * @return sum of values
- * @deprecated call {@link MathUtils#sum(int[])}
- */
- // @Deprecated
- public static getBitCountSum(moduleBitCount: Int32Array): int {
- return MathUtils.sum(moduleBitCount);
- }
+ /**
+ * @param moduleBitCount values to sum
+ * @return sum of values
+ * @deprecated call {@link MathUtils#sum(int[])}
+ */
+ // @Deprecated
+ public static getBitCountSum(moduleBitCount: Int32Array): int {
+ return MathUtils.sum(moduleBitCount);
+ }
- public static toIntArray(list: /*Collection*/ int[]): Int32Array {
- if (list == null || !list.length) {
- return PDF417Common.EMPTY_INT_ARRAY;
- }
- const result = new Int32Array(list.length);
- let i: int = 0;
- for (const integer of list) {
- result[i++] = integer;
- }
- return result;
+ public static toIntArray(list: /* Collection */ int[]): Int32Array {
+ if (list == null || !list.length) {
+ return PDF417Common.EMPTY_INT_ARRAY;
+ }
+ const result = new Int32Array(list.length);
+ let i: int = 0;
+ for (const integer of list) {
+ result[i++] = integer;
}
+ return result;
+ }
- /**
- * @param symbol encoded symbol to translate to a codeword
- * @return the codeword corresponding to the symbol.
- */
- public static getCodeword(symbol: number/*int*/): number/*int*/ {
- const i = Arrays.binarySearch(PDF417Common.SYMBOL_TABLE, symbol & 0x3FFFF);
- if (i < 0) {
- return -1;
- }
- return (PDF417Common.CODEWORD_TABLE[i] - 1) % PDF417Common.NUMBER_OF_CODEWORDS;
+ /**
+ * @param symbol encoded symbol to translate to a codeword
+ * @return the codeword corresponding to the symbol.
+ */
+ public static getCodeword(symbol: number/* int */): number/* int */ {
+ const i = Arrays.binarySearch(PDF417Common.SYMBOL_TABLE, symbol & 0x3FFFF);
+ if (i < 0) {
+ return -1;
}
+ return (PDF417Common.CODEWORD_TABLE[i] - 1) % PDF417Common.NUMBER_OF_CODEWORDS;
+ }
- /**
- * The sorted table of all possible symbols. Extracted from the PDF417
- * specification. The index of a symbol in this table corresponds to the
- * index into the codeword table.
- */
- public static /*final int[]*/ SYMBOL_TABLE = Int32Array.from([
- 0x1025e, 0x1027a, 0x1029e, 0x102bc, 0x102f2, 0x102f4, 0x1032e, 0x1034e, 0x1035c, 0x10396, 0x103a6, 0x103ac,
- 0x10422, 0x10428, 0x10436, 0x10442, 0x10444, 0x10448, 0x10450, 0x1045e, 0x10466, 0x1046c, 0x1047a, 0x10482,
- 0x1049e, 0x104a0, 0x104bc, 0x104c6, 0x104d8, 0x104ee, 0x104f2, 0x104f4, 0x10504, 0x10508, 0x10510, 0x1051e,
- 0x10520, 0x1053c, 0x10540, 0x10578, 0x10586, 0x1058c, 0x10598, 0x105b0, 0x105be, 0x105ce, 0x105dc, 0x105e2,
- 0x105e4, 0x105e8, 0x105f6, 0x1062e, 0x1064e, 0x1065c, 0x1068e, 0x1069c, 0x106b8, 0x106de, 0x106fa, 0x10716,
- 0x10726, 0x1072c, 0x10746, 0x1074c, 0x10758, 0x1076e, 0x10792, 0x10794, 0x107a2, 0x107a4, 0x107a8, 0x107b6,
- 0x10822, 0x10828, 0x10842, 0x10848, 0x10850, 0x1085e, 0x10866, 0x1086c, 0x1087a, 0x10882, 0x10884, 0x10890,
- 0x1089e, 0x108a0, 0x108bc, 0x108c6, 0x108cc, 0x108d8, 0x108ee, 0x108f2, 0x108f4, 0x10902, 0x10908, 0x1091e,
- 0x10920, 0x1093c, 0x10940, 0x10978, 0x10986, 0x10998, 0x109b0, 0x109be, 0x109ce, 0x109dc, 0x109e2, 0x109e4,
- 0x109e8, 0x109f6, 0x10a08, 0x10a10, 0x10a1e, 0x10a20, 0x10a3c, 0x10a40, 0x10a78, 0x10af0, 0x10b06, 0x10b0c,
- 0x10b18, 0x10b30, 0x10b3e, 0x10b60, 0x10b7c, 0x10b8e, 0x10b9c, 0x10bb8, 0x10bc2, 0x10bc4, 0x10bc8, 0x10bd0,
- 0x10bde, 0x10be6, 0x10bec, 0x10c2e, 0x10c4e, 0x10c5c, 0x10c62, 0x10c64, 0x10c68, 0x10c76, 0x10c8e, 0x10c9c,
- 0x10cb8, 0x10cc2, 0x10cc4, 0x10cc8, 0x10cd0, 0x10cde, 0x10ce6, 0x10cec, 0x10cfa, 0x10d0e, 0x10d1c, 0x10d38,
- 0x10d70, 0x10d7e, 0x10d82, 0x10d84, 0x10d88, 0x10d90, 0x10d9e, 0x10da0, 0x10dbc, 0x10dc6, 0x10dcc, 0x10dd8,
- 0x10dee, 0x10df2, 0x10df4, 0x10e16, 0x10e26, 0x10e2c, 0x10e46, 0x10e58, 0x10e6e, 0x10e86, 0x10e8c, 0x10e98,
- 0x10eb0, 0x10ebe, 0x10ece, 0x10edc, 0x10f0a, 0x10f12, 0x10f14, 0x10f22, 0x10f28, 0x10f36, 0x10f42, 0x10f44,
- 0x10f48, 0x10f50, 0x10f5e, 0x10f66, 0x10f6c, 0x10fb2, 0x10fb4, 0x11022, 0x11028, 0x11042, 0x11048, 0x11050,
- 0x1105e, 0x1107a, 0x11082, 0x11084, 0x11090, 0x1109e, 0x110a0, 0x110bc, 0x110c6, 0x110cc, 0x110d8, 0x110ee,
- 0x110f2, 0x110f4, 0x11102, 0x1111e, 0x11120, 0x1113c, 0x11140, 0x11178, 0x11186, 0x11198, 0x111b0, 0x111be,
- 0x111ce, 0x111dc, 0x111e2, 0x111e4, 0x111e8, 0x111f6, 0x11208, 0x1121e, 0x11220, 0x11278, 0x112f0, 0x1130c,
- 0x11330, 0x1133e, 0x11360, 0x1137c, 0x1138e, 0x1139c, 0x113b8, 0x113c2, 0x113c8, 0x113d0, 0x113de, 0x113e6,
- 0x113ec, 0x11408, 0x11410, 0x1141e, 0x11420, 0x1143c, 0x11440, 0x11478, 0x114f0, 0x115e0, 0x1160c, 0x11618,
- 0x11630, 0x1163e, 0x11660, 0x1167c, 0x116c0, 0x116f8, 0x1171c, 0x11738, 0x11770, 0x1177e, 0x11782, 0x11784,
- 0x11788, 0x11790, 0x1179e, 0x117a0, 0x117bc, 0x117c6, 0x117cc, 0x117d8, 0x117ee, 0x1182e, 0x11834, 0x1184e,
- 0x1185c, 0x11862, 0x11864, 0x11868, 0x11876, 0x1188e, 0x1189c, 0x118b8, 0x118c2, 0x118c8, 0x118d0, 0x118de,
- 0x118e6, 0x118ec, 0x118fa, 0x1190e, 0x1191c, 0x11938, 0x11970, 0x1197e, 0x11982, 0x11984, 0x11990, 0x1199e,
- 0x119a0, 0x119bc, 0x119c6, 0x119cc, 0x119d8, 0x119ee, 0x119f2, 0x119f4, 0x11a0e, 0x11a1c, 0x11a38, 0x11a70,
- 0x11a7e, 0x11ae0, 0x11afc, 0x11b08, 0x11b10, 0x11b1e, 0x11b20, 0x11b3c, 0x11b40, 0x11b78, 0x11b8c, 0x11b98,
- 0x11bb0, 0x11bbe, 0x11bce, 0x11bdc, 0x11be2, 0x11be4, 0x11be8, 0x11bf6, 0x11c16, 0x11c26, 0x11c2c, 0x11c46,
- 0x11c4c, 0x11c58, 0x11c6e, 0x11c86, 0x11c98, 0x11cb0, 0x11cbe, 0x11cce, 0x11cdc, 0x11ce2, 0x11ce4, 0x11ce8,
- 0x11cf6, 0x11d06, 0x11d0c, 0x11d18, 0x11d30, 0x11d3e, 0x11d60, 0x11d7c, 0x11d8e, 0x11d9c, 0x11db8, 0x11dc4,
- 0x11dc8, 0x11dd0, 0x11dde, 0x11de6, 0x11dec, 0x11dfa, 0x11e0a, 0x11e12, 0x11e14, 0x11e22, 0x11e24, 0x11e28,
- 0x11e36, 0x11e42, 0x11e44, 0x11e50, 0x11e5e, 0x11e66, 0x11e6c, 0x11e82, 0x11e84, 0x11e88, 0x11e90, 0x11e9e,
- 0x11ea0, 0x11ebc, 0x11ec6, 0x11ecc, 0x11ed8, 0x11eee, 0x11f1a, 0x11f2e, 0x11f32, 0x11f34, 0x11f4e, 0x11f5c,
- 0x11f62, 0x11f64, 0x11f68, 0x11f76, 0x12048, 0x1205e, 0x12082, 0x12084, 0x12090, 0x1209e, 0x120a0, 0x120bc,
- 0x120d8, 0x120f2, 0x120f4, 0x12108, 0x1211e, 0x12120, 0x1213c, 0x12140, 0x12178, 0x12186, 0x12198, 0x121b0,
- 0x121be, 0x121e2, 0x121e4, 0x121e8, 0x121f6, 0x12204, 0x12210, 0x1221e, 0x12220, 0x12278, 0x122f0, 0x12306,
- 0x1230c, 0x12330, 0x1233e, 0x12360, 0x1237c, 0x1238e, 0x1239c, 0x123b8, 0x123c2, 0x123c8, 0x123d0, 0x123e6,
- 0x123ec, 0x1241e, 0x12420, 0x1243c, 0x124f0, 0x125e0, 0x12618, 0x1263e, 0x12660, 0x1267c, 0x126c0, 0x126f8,
- 0x12738, 0x12770, 0x1277e, 0x12782, 0x12784, 0x12790, 0x1279e, 0x127a0, 0x127bc, 0x127c6, 0x127cc, 0x127d8,
- 0x127ee, 0x12820, 0x1283c, 0x12840, 0x12878, 0x128f0, 0x129e0, 0x12bc0, 0x12c18, 0x12c30, 0x12c3e, 0x12c60,
- 0x12c7c, 0x12cc0, 0x12cf8, 0x12df0, 0x12e1c, 0x12e38, 0x12e70, 0x12e7e, 0x12ee0, 0x12efc, 0x12f04, 0x12f08,
- 0x12f10, 0x12f20, 0x12f3c, 0x12f40, 0x12f78, 0x12f86, 0x12f8c, 0x12f98, 0x12fb0, 0x12fbe, 0x12fce, 0x12fdc,
- 0x1302e, 0x1304e, 0x1305c, 0x13062, 0x13068, 0x1308e, 0x1309c, 0x130b8, 0x130c2, 0x130c8, 0x130d0, 0x130de,
- 0x130ec, 0x130fa, 0x1310e, 0x13138, 0x13170, 0x1317e, 0x13182, 0x13184, 0x13190, 0x1319e, 0x131a0, 0x131bc,
- 0x131c6, 0x131cc, 0x131d8, 0x131f2, 0x131f4, 0x1320e, 0x1321c, 0x13270, 0x1327e, 0x132e0, 0x132fc, 0x13308,
- 0x1331e, 0x13320, 0x1333c, 0x13340, 0x13378, 0x13386, 0x13398, 0x133b0, 0x133be, 0x133ce, 0x133dc, 0x133e2,
- 0x133e4, 0x133e8, 0x133f6, 0x1340e, 0x1341c, 0x13438, 0x13470, 0x1347e, 0x134e0, 0x134fc, 0x135c0, 0x135f8,
- 0x13608, 0x13610, 0x1361e, 0x13620, 0x1363c, 0x13640, 0x13678, 0x136f0, 0x1370c, 0x13718, 0x13730, 0x1373e,
- 0x13760, 0x1377c, 0x1379c, 0x137b8, 0x137c2, 0x137c4, 0x137c8, 0x137d0, 0x137de, 0x137e6, 0x137ec, 0x13816,
- 0x13826, 0x1382c, 0x13846, 0x1384c, 0x13858, 0x1386e, 0x13874, 0x13886, 0x13898, 0x138b0, 0x138be, 0x138ce,
- 0x138dc, 0x138e2, 0x138e4, 0x138e8, 0x13906, 0x1390c, 0x13930, 0x1393e, 0x13960, 0x1397c, 0x1398e, 0x1399c,
- 0x139b8, 0x139c8, 0x139d0, 0x139de, 0x139e6, 0x139ec, 0x139fa, 0x13a06, 0x13a0c, 0x13a18, 0x13a30, 0x13a3e,
- 0x13a60, 0x13a7c, 0x13ac0, 0x13af8, 0x13b0e, 0x13b1c, 0x13b38, 0x13b70, 0x13b7e, 0x13b88, 0x13b90, 0x13b9e,
- 0x13ba0, 0x13bbc, 0x13bcc, 0x13bd8, 0x13bee, 0x13bf2, 0x13bf4, 0x13c12, 0x13c14, 0x13c22, 0x13c24, 0x13c28,
- 0x13c36, 0x13c42, 0x13c48, 0x13c50, 0x13c5e, 0x13c66, 0x13c6c, 0x13c82, 0x13c84, 0x13c90, 0x13c9e, 0x13ca0,
- 0x13cbc, 0x13cc6, 0x13ccc, 0x13cd8, 0x13cee, 0x13d02, 0x13d04, 0x13d08, 0x13d10, 0x13d1e, 0x13d20, 0x13d3c,
- 0x13d40, 0x13d78, 0x13d86, 0x13d8c, 0x13d98, 0x13db0, 0x13dbe, 0x13dce, 0x13ddc, 0x13de4, 0x13de8, 0x13df6,
- 0x13e1a, 0x13e2e, 0x13e32, 0x13e34, 0x13e4e, 0x13e5c, 0x13e62, 0x13e64, 0x13e68, 0x13e76, 0x13e8e, 0x13e9c,
- 0x13eb8, 0x13ec2, 0x13ec4, 0x13ec8, 0x13ed0, 0x13ede, 0x13ee6, 0x13eec, 0x13f26, 0x13f2c, 0x13f3a, 0x13f46,
- 0x13f4c, 0x13f58, 0x13f6e, 0x13f72, 0x13f74, 0x14082, 0x1409e, 0x140a0, 0x140bc, 0x14104, 0x14108, 0x14110,
- 0x1411e, 0x14120, 0x1413c, 0x14140, 0x14178, 0x1418c, 0x14198, 0x141b0, 0x141be, 0x141e2, 0x141e4, 0x141e8,
- 0x14208, 0x14210, 0x1421e, 0x14220, 0x1423c, 0x14240, 0x14278, 0x142f0, 0x14306, 0x1430c, 0x14318, 0x14330,
- 0x1433e, 0x14360, 0x1437c, 0x1438e, 0x143c2, 0x143c4, 0x143c8, 0x143d0, 0x143e6, 0x143ec, 0x14408, 0x14410,
- 0x1441e, 0x14420, 0x1443c, 0x14440, 0x14478, 0x144f0, 0x145e0, 0x1460c, 0x14618, 0x14630, 0x1463e, 0x14660,
- 0x1467c, 0x146c0, 0x146f8, 0x1471c, 0x14738, 0x14770, 0x1477e, 0x14782, 0x14784, 0x14788, 0x14790, 0x147a0,
- 0x147bc, 0x147c6, 0x147cc, 0x147d8, 0x147ee, 0x14810, 0x14820, 0x1483c, 0x14840, 0x14878, 0x148f0, 0x149e0,
- 0x14bc0, 0x14c30, 0x14c3e, 0x14c60, 0x14c7c, 0x14cc0, 0x14cf8, 0x14df0, 0x14e38, 0x14e70, 0x14e7e, 0x14ee0,
- 0x14efc, 0x14f04, 0x14f08, 0x14f10, 0x14f1e, 0x14f20, 0x14f3c, 0x14f40, 0x14f78, 0x14f86, 0x14f8c, 0x14f98,
- 0x14fb0, 0x14fce, 0x14fdc, 0x15020, 0x15040, 0x15078, 0x150f0, 0x151e0, 0x153c0, 0x15860, 0x1587c, 0x158c0,
- 0x158f8, 0x159f0, 0x15be0, 0x15c70, 0x15c7e, 0x15ce0, 0x15cfc, 0x15dc0, 0x15df8, 0x15e08, 0x15e10, 0x15e20,
- 0x15e40, 0x15e78, 0x15ef0, 0x15f0c, 0x15f18, 0x15f30, 0x15f60, 0x15f7c, 0x15f8e, 0x15f9c, 0x15fb8, 0x1604e,
- 0x1605c, 0x1608e, 0x1609c, 0x160b8, 0x160c2, 0x160c4, 0x160c8, 0x160de, 0x1610e, 0x1611c, 0x16138, 0x16170,
- 0x1617e, 0x16184, 0x16188, 0x16190, 0x1619e, 0x161a0, 0x161bc, 0x161c6, 0x161cc, 0x161d8, 0x161f2, 0x161f4,
- 0x1620e, 0x1621c, 0x16238, 0x16270, 0x1627e, 0x162e0, 0x162fc, 0x16304, 0x16308, 0x16310, 0x1631e, 0x16320,
- 0x1633c, 0x16340, 0x16378, 0x16386, 0x1638c, 0x16398, 0x163b0, 0x163be, 0x163ce, 0x163dc, 0x163e2, 0x163e4,
- 0x163e8, 0x163f6, 0x1640e, 0x1641c, 0x16438, 0x16470, 0x1647e, 0x164e0, 0x164fc, 0x165c0, 0x165f8, 0x16610,
- 0x1661e, 0x16620, 0x1663c, 0x16640, 0x16678, 0x166f0, 0x16718, 0x16730, 0x1673e, 0x16760, 0x1677c, 0x1678e,
- 0x1679c, 0x167b8, 0x167c2, 0x167c4, 0x167c8, 0x167d0, 0x167de, 0x167e6, 0x167ec, 0x1681c, 0x16838, 0x16870,
- 0x168e0, 0x168fc, 0x169c0, 0x169f8, 0x16bf0, 0x16c10, 0x16c1e, 0x16c20, 0x16c3c, 0x16c40, 0x16c78, 0x16cf0,
- 0x16de0, 0x16e18, 0x16e30, 0x16e3e, 0x16e60, 0x16e7c, 0x16ec0, 0x16ef8, 0x16f1c, 0x16f38, 0x16f70, 0x16f7e,
- 0x16f84, 0x16f88, 0x16f90, 0x16f9e, 0x16fa0, 0x16fbc, 0x16fc6, 0x16fcc, 0x16fd8, 0x17026, 0x1702c, 0x17046,
- 0x1704c, 0x17058, 0x1706e, 0x17086, 0x1708c, 0x17098, 0x170b0, 0x170be, 0x170ce, 0x170dc, 0x170e8, 0x17106,
- 0x1710c, 0x17118, 0x17130, 0x1713e, 0x17160, 0x1717c, 0x1718e, 0x1719c, 0x171b8, 0x171c2, 0x171c4, 0x171c8,
- 0x171d0, 0x171de, 0x171e6, 0x171ec, 0x171fa, 0x17206, 0x1720c, 0x17218, 0x17230, 0x1723e, 0x17260, 0x1727c,
- 0x172c0, 0x172f8, 0x1730e, 0x1731c, 0x17338, 0x17370, 0x1737e, 0x17388, 0x17390, 0x1739e, 0x173a0, 0x173bc,
- 0x173cc, 0x173d8, 0x173ee, 0x173f2, 0x173f4, 0x1740c, 0x17418, 0x17430, 0x1743e, 0x17460, 0x1747c, 0x174c0,
- 0x174f8, 0x175f0, 0x1760e, 0x1761c, 0x17638, 0x17670, 0x1767e, 0x176e0, 0x176fc, 0x17708, 0x17710, 0x1771e,
- 0x17720, 0x1773c, 0x17740, 0x17778, 0x17798, 0x177b0, 0x177be, 0x177dc, 0x177e2, 0x177e4, 0x177e8, 0x17822,
- 0x17824, 0x17828, 0x17836, 0x17842, 0x17844, 0x17848, 0x17850, 0x1785e, 0x17866, 0x1786c, 0x17882, 0x17884,
- 0x17888, 0x17890, 0x1789e, 0x178a0, 0x178bc, 0x178c6, 0x178cc, 0x178d8, 0x178ee, 0x178f2, 0x178f4, 0x17902,
- 0x17904, 0x17908, 0x17910, 0x1791e, 0x17920, 0x1793c, 0x17940, 0x17978, 0x17986, 0x1798c, 0x17998, 0x179b0,
- 0x179be, 0x179ce, 0x179dc, 0x179e2, 0x179e4, 0x179e8, 0x179f6, 0x17a04, 0x17a08, 0x17a10, 0x17a1e, 0x17a20,
- 0x17a3c, 0x17a40, 0x17a78, 0x17af0, 0x17b06, 0x17b0c, 0x17b18, 0x17b30, 0x17b3e, 0x17b60, 0x17b7c, 0x17b8e,
- 0x17b9c, 0x17bb8, 0x17bc4, 0x17bc8, 0x17bd0, 0x17bde, 0x17be6, 0x17bec, 0x17c2e, 0x17c32, 0x17c34, 0x17c4e,
- 0x17c5c, 0x17c62, 0x17c64, 0x17c68, 0x17c76, 0x17c8e, 0x17c9c, 0x17cb8, 0x17cc2, 0x17cc4, 0x17cc8, 0x17cd0,
- 0x17cde, 0x17ce6, 0x17cec, 0x17d0e, 0x17d1c, 0x17d38, 0x17d70, 0x17d82, 0x17d84, 0x17d88, 0x17d90, 0x17d9e,
- 0x17da0, 0x17dbc, 0x17dc6, 0x17dcc, 0x17dd8, 0x17dee, 0x17e26, 0x17e2c, 0x17e3a, 0x17e46, 0x17e4c, 0x17e58,
- 0x17e6e, 0x17e72, 0x17e74, 0x17e86, 0x17e8c, 0x17e98, 0x17eb0, 0x17ece, 0x17edc, 0x17ee2, 0x17ee4, 0x17ee8,
- 0x17ef6, 0x1813a, 0x18172, 0x18174, 0x18216, 0x18226, 0x1823a, 0x1824c, 0x18258, 0x1826e, 0x18272, 0x18274,
- 0x18298, 0x182be, 0x182e2, 0x182e4, 0x182e8, 0x182f6, 0x1835e, 0x1837a, 0x183ae, 0x183d6, 0x18416, 0x18426,
- 0x1842c, 0x1843a, 0x18446, 0x18458, 0x1846e, 0x18472, 0x18474, 0x18486, 0x184b0, 0x184be, 0x184ce, 0x184dc,
- 0x184e2, 0x184e4, 0x184e8, 0x184f6, 0x18506, 0x1850c, 0x18518, 0x18530, 0x1853e, 0x18560, 0x1857c, 0x1858e,
- 0x1859c, 0x185b8, 0x185c2, 0x185c4, 0x185c8, 0x185d0, 0x185de, 0x185e6, 0x185ec, 0x185fa, 0x18612, 0x18614,
- 0x18622, 0x18628, 0x18636, 0x18642, 0x18650, 0x1865e, 0x1867a, 0x18682, 0x18684, 0x18688, 0x18690, 0x1869e,
- 0x186a0, 0x186bc, 0x186c6, 0x186cc, 0x186d8, 0x186ee, 0x186f2, 0x186f4, 0x1872e, 0x1874e, 0x1875c, 0x18796,
- 0x187a6, 0x187ac, 0x187d2, 0x187d4, 0x18826, 0x1882c, 0x1883a, 0x18846, 0x1884c, 0x18858, 0x1886e, 0x18872,
- 0x18874, 0x18886, 0x18898, 0x188b0, 0x188be, 0x188ce, 0x188dc, 0x188e2, 0x188e4, 0x188e8, 0x188f6, 0x1890c,
- 0x18930, 0x1893e, 0x18960, 0x1897c, 0x1898e, 0x189b8, 0x189c2, 0x189c8, 0x189d0, 0x189de, 0x189e6, 0x189ec,
- 0x189fa, 0x18a18, 0x18a30, 0x18a3e, 0x18a60, 0x18a7c, 0x18ac0, 0x18af8, 0x18b1c, 0x18b38, 0x18b70, 0x18b7e,
- 0x18b82, 0x18b84, 0x18b88, 0x18b90, 0x18b9e, 0x18ba0, 0x18bbc, 0x18bc6, 0x18bcc, 0x18bd8, 0x18bee, 0x18bf2,
- 0x18bf4, 0x18c22, 0x18c24, 0x18c28, 0x18c36, 0x18c42, 0x18c48, 0x18c50, 0x18c5e, 0x18c66, 0x18c7a, 0x18c82,
- 0x18c84, 0x18c90, 0x18c9e, 0x18ca0, 0x18cbc, 0x18ccc, 0x18cf2, 0x18cf4, 0x18d04, 0x18d08, 0x18d10, 0x18d1e,
- 0x18d20, 0x18d3c, 0x18d40, 0x18d78, 0x18d86, 0x18d98, 0x18dce, 0x18de2, 0x18de4, 0x18de8, 0x18e2e, 0x18e32,
- 0x18e34, 0x18e4e, 0x18e5c, 0x18e62, 0x18e64, 0x18e68, 0x18e8e, 0x18e9c, 0x18eb8, 0x18ec2, 0x18ec4, 0x18ec8,
- 0x18ed0, 0x18efa, 0x18f16, 0x18f26, 0x18f2c, 0x18f46, 0x18f4c, 0x18f58, 0x18f6e, 0x18f8a, 0x18f92, 0x18f94,
- 0x18fa2, 0x18fa4, 0x18fa8, 0x18fb6, 0x1902c, 0x1903a, 0x19046, 0x1904c, 0x19058, 0x19072, 0x19074, 0x19086,
- 0x19098, 0x190b0, 0x190be, 0x190ce, 0x190dc, 0x190e2, 0x190e8, 0x190f6, 0x19106, 0x1910c, 0x19130, 0x1913e,
- 0x19160, 0x1917c, 0x1918e, 0x1919c, 0x191b8, 0x191c2, 0x191c8, 0x191d0, 0x191de, 0x191e6, 0x191ec, 0x191fa,
- 0x19218, 0x1923e, 0x19260, 0x1927c, 0x192c0, 0x192f8, 0x19338, 0x19370, 0x1937e, 0x19382, 0x19384, 0x19390,
- 0x1939e, 0x193a0, 0x193bc, 0x193c6, 0x193cc, 0x193d8, 0x193ee, 0x193f2, 0x193f4, 0x19430, 0x1943e, 0x19460,
- 0x1947c, 0x194c0, 0x194f8, 0x195f0, 0x19638, 0x19670, 0x1967e, 0x196e0, 0x196fc, 0x19702, 0x19704, 0x19708,
- 0x19710, 0x19720, 0x1973c, 0x19740, 0x19778, 0x19786, 0x1978c, 0x19798, 0x197b0, 0x197be, 0x197ce, 0x197dc,
- 0x197e2, 0x197e4, 0x197e8, 0x19822, 0x19824, 0x19842, 0x19848, 0x19850, 0x1985e, 0x19866, 0x1987a, 0x19882,
- 0x19884, 0x19890, 0x1989e, 0x198a0, 0x198bc, 0x198cc, 0x198f2, 0x198f4, 0x19902, 0x19908, 0x1991e, 0x19920,
- 0x1993c, 0x19940, 0x19978, 0x19986, 0x19998, 0x199ce, 0x199e2, 0x199e4, 0x199e8, 0x19a08, 0x19a10, 0x19a1e,
- 0x19a20, 0x19a3c, 0x19a40, 0x19a78, 0x19af0, 0x19b18, 0x19b3e, 0x19b60, 0x19b9c, 0x19bc2, 0x19bc4, 0x19bc8,
- 0x19bd0, 0x19be6, 0x19c2e, 0x19c34, 0x19c4e, 0x19c5c, 0x19c62, 0x19c64, 0x19c68, 0x19c8e, 0x19c9c, 0x19cb8,
- 0x19cc2, 0x19cc8, 0x19cd0, 0x19ce6, 0x19cfa, 0x19d0e, 0x19d1c, 0x19d38, 0x19d70, 0x19d7e, 0x19d82, 0x19d84,
- 0x19d88, 0x19d90, 0x19da0, 0x19dcc, 0x19df2, 0x19df4, 0x19e16, 0x19e26, 0x19e2c, 0x19e46, 0x19e4c, 0x19e58,
- 0x19e74, 0x19e86, 0x19e8c, 0x19e98, 0x19eb0, 0x19ebe, 0x19ece, 0x19ee2, 0x19ee4, 0x19ee8, 0x19f0a, 0x19f12,
- 0x19f14, 0x19f22, 0x19f24, 0x19f28, 0x19f42, 0x19f44, 0x19f48, 0x19f50, 0x19f5e, 0x19f6c, 0x19f9a, 0x19fae,
- 0x19fb2, 0x19fb4, 0x1a046, 0x1a04c, 0x1a072, 0x1a074, 0x1a086, 0x1a08c, 0x1a098, 0x1a0b0, 0x1a0be, 0x1a0e2,
- 0x1a0e4, 0x1a0e8, 0x1a0f6, 0x1a106, 0x1a10c, 0x1a118, 0x1a130, 0x1a13e, 0x1a160, 0x1a17c, 0x1a18e, 0x1a19c,
- 0x1a1b8, 0x1a1c2, 0x1a1c4, 0x1a1c8, 0x1a1d0, 0x1a1de, 0x1a1e6, 0x1a1ec, 0x1a218, 0x1a230, 0x1a23e, 0x1a260,
- 0x1a27c, 0x1a2c0, 0x1a2f8, 0x1a31c, 0x1a338, 0x1a370, 0x1a37e, 0x1a382, 0x1a384, 0x1a388, 0x1a390, 0x1a39e,
- 0x1a3a0, 0x1a3bc, 0x1a3c6, 0x1a3cc, 0x1a3d8, 0x1a3ee, 0x1a3f2, 0x1a3f4, 0x1a418, 0x1a430, 0x1a43e, 0x1a460,
- 0x1a47c, 0x1a4c0, 0x1a4f8, 0x1a5f0, 0x1a61c, 0x1a638, 0x1a670, 0x1a67e, 0x1a6e0, 0x1a6fc, 0x1a702, 0x1a704,
- 0x1a708, 0x1a710, 0x1a71e, 0x1a720, 0x1a73c, 0x1a740, 0x1a778, 0x1a786, 0x1a78c, 0x1a798, 0x1a7b0, 0x1a7be,
- 0x1a7ce, 0x1a7dc, 0x1a7e2, 0x1a7e4, 0x1a7e8, 0x1a830, 0x1a860, 0x1a87c, 0x1a8c0, 0x1a8f8, 0x1a9f0, 0x1abe0,
- 0x1ac70, 0x1ac7e, 0x1ace0, 0x1acfc, 0x1adc0, 0x1adf8, 0x1ae04, 0x1ae08, 0x1ae10, 0x1ae20, 0x1ae3c, 0x1ae40,
- 0x1ae78, 0x1aef0, 0x1af06, 0x1af0c, 0x1af18, 0x1af30, 0x1af3e, 0x1af60, 0x1af7c, 0x1af8e, 0x1af9c, 0x1afb8,
- 0x1afc4, 0x1afc8, 0x1afd0, 0x1afde, 0x1b042, 0x1b05e, 0x1b07a, 0x1b082, 0x1b084, 0x1b088, 0x1b090, 0x1b09e,
- 0x1b0a0, 0x1b0bc, 0x1b0cc, 0x1b0f2, 0x1b0f4, 0x1b102, 0x1b104, 0x1b108, 0x1b110, 0x1b11e, 0x1b120, 0x1b13c,
- 0x1b140, 0x1b178, 0x1b186, 0x1b198, 0x1b1ce, 0x1b1e2, 0x1b1e4, 0x1b1e8, 0x1b204, 0x1b208, 0x1b210, 0x1b21e,
- 0x1b220, 0x1b23c, 0x1b240, 0x1b278, 0x1b2f0, 0x1b30c, 0x1b33e, 0x1b360, 0x1b39c, 0x1b3c2, 0x1b3c4, 0x1b3c8,
- 0x1b3d0, 0x1b3e6, 0x1b410, 0x1b41e, 0x1b420, 0x1b43c, 0x1b440, 0x1b478, 0x1b4f0, 0x1b5e0, 0x1b618, 0x1b660,
- 0x1b67c, 0x1b6c0, 0x1b738, 0x1b782, 0x1b784, 0x1b788, 0x1b790, 0x1b79e, 0x1b7a0, 0x1b7cc, 0x1b82e, 0x1b84e,
- 0x1b85c, 0x1b88e, 0x1b89c, 0x1b8b8, 0x1b8c2, 0x1b8c4, 0x1b8c8, 0x1b8d0, 0x1b8e6, 0x1b8fa, 0x1b90e, 0x1b91c,
- 0x1b938, 0x1b970, 0x1b97e, 0x1b982, 0x1b984, 0x1b988, 0x1b990, 0x1b99e, 0x1b9a0, 0x1b9cc, 0x1b9f2, 0x1b9f4,
- 0x1ba0e, 0x1ba1c, 0x1ba38, 0x1ba70, 0x1ba7e, 0x1bae0, 0x1bafc, 0x1bb08, 0x1bb10, 0x1bb20, 0x1bb3c, 0x1bb40,
- 0x1bb98, 0x1bbce, 0x1bbe2, 0x1bbe4, 0x1bbe8, 0x1bc16, 0x1bc26, 0x1bc2c, 0x1bc46, 0x1bc4c, 0x1bc58, 0x1bc72,
- 0x1bc74, 0x1bc86, 0x1bc8c, 0x1bc98, 0x1bcb0, 0x1bcbe, 0x1bcce, 0x1bce2, 0x1bce4, 0x1bce8, 0x1bd06, 0x1bd0c,
- 0x1bd18, 0x1bd30, 0x1bd3e, 0x1bd60, 0x1bd7c, 0x1bd9c, 0x1bdc2, 0x1bdc4, 0x1bdc8, 0x1bdd0, 0x1bde6, 0x1bdfa,
- 0x1be12, 0x1be14, 0x1be22, 0x1be24, 0x1be28, 0x1be42, 0x1be44, 0x1be48, 0x1be50, 0x1be5e, 0x1be66, 0x1be82,
- 0x1be84, 0x1be88, 0x1be90, 0x1be9e, 0x1bea0, 0x1bebc, 0x1becc, 0x1bef4, 0x1bf1a, 0x1bf2e, 0x1bf32, 0x1bf34,
- 0x1bf4e, 0x1bf5c, 0x1bf62, 0x1bf64, 0x1bf68, 0x1c09a, 0x1c0b2, 0x1c0b4, 0x1c11a, 0x1c132, 0x1c134, 0x1c162,
- 0x1c164, 0x1c168, 0x1c176, 0x1c1ba, 0x1c21a, 0x1c232, 0x1c234, 0x1c24e, 0x1c25c, 0x1c262, 0x1c264, 0x1c268,
- 0x1c276, 0x1c28e, 0x1c2c2, 0x1c2c4, 0x1c2c8, 0x1c2d0, 0x1c2de, 0x1c2e6, 0x1c2ec, 0x1c2fa, 0x1c316, 0x1c326,
- 0x1c33a, 0x1c346, 0x1c34c, 0x1c372, 0x1c374, 0x1c41a, 0x1c42e, 0x1c432, 0x1c434, 0x1c44e, 0x1c45c, 0x1c462,
- 0x1c464, 0x1c468, 0x1c476, 0x1c48e, 0x1c49c, 0x1c4b8, 0x1c4c2, 0x1c4c8, 0x1c4d0, 0x1c4de, 0x1c4e6, 0x1c4ec,
- 0x1c4fa, 0x1c51c, 0x1c538, 0x1c570, 0x1c57e, 0x1c582, 0x1c584, 0x1c588, 0x1c590, 0x1c59e, 0x1c5a0, 0x1c5bc,
- 0x1c5c6, 0x1c5cc, 0x1c5d8, 0x1c5ee, 0x1c5f2, 0x1c5f4, 0x1c616, 0x1c626, 0x1c62c, 0x1c63a, 0x1c646, 0x1c64c,
- 0x1c658, 0x1c66e, 0x1c672, 0x1c674, 0x1c686, 0x1c68c, 0x1c698, 0x1c6b0, 0x1c6be, 0x1c6ce, 0x1c6dc, 0x1c6e2,
- 0x1c6e4, 0x1c6e8, 0x1c712, 0x1c714, 0x1c722, 0x1c728, 0x1c736, 0x1c742, 0x1c744, 0x1c748, 0x1c750, 0x1c75e,
- 0x1c766, 0x1c76c, 0x1c77a, 0x1c7ae, 0x1c7d6, 0x1c7ea, 0x1c81a, 0x1c82e, 0x1c832, 0x1c834, 0x1c84e, 0x1c85c,
- 0x1c862, 0x1c864, 0x1c868, 0x1c876, 0x1c88e, 0x1c89c, 0x1c8b8, 0x1c8c2, 0x1c8c8, 0x1c8d0, 0x1c8de, 0x1c8e6,
- 0x1c8ec, 0x1c8fa, 0x1c90e, 0x1c938, 0x1c970, 0x1c97e, 0x1c982, 0x1c984, 0x1c990, 0x1c99e, 0x1c9a0, 0x1c9bc,
- 0x1c9c6, 0x1c9cc, 0x1c9d8, 0x1c9ee, 0x1c9f2, 0x1c9f4, 0x1ca38, 0x1ca70, 0x1ca7e, 0x1cae0, 0x1cafc, 0x1cb02,
- 0x1cb04, 0x1cb08, 0x1cb10, 0x1cb20, 0x1cb3c, 0x1cb40, 0x1cb78, 0x1cb86, 0x1cb8c, 0x1cb98, 0x1cbb0, 0x1cbbe,
- 0x1cbce, 0x1cbdc, 0x1cbe2, 0x1cbe4, 0x1cbe8, 0x1cbf6, 0x1cc16, 0x1cc26, 0x1cc2c, 0x1cc3a, 0x1cc46, 0x1cc58,
- 0x1cc72, 0x1cc74, 0x1cc86, 0x1ccb0, 0x1ccbe, 0x1ccce, 0x1cce2, 0x1cce4, 0x1cce8, 0x1cd06, 0x1cd0c, 0x1cd18,
- 0x1cd30, 0x1cd3e, 0x1cd60, 0x1cd7c, 0x1cd9c, 0x1cdc2, 0x1cdc4, 0x1cdc8, 0x1cdd0, 0x1cdde, 0x1cde6, 0x1cdfa,
- 0x1ce22, 0x1ce28, 0x1ce42, 0x1ce50, 0x1ce5e, 0x1ce66, 0x1ce7a, 0x1ce82, 0x1ce84, 0x1ce88, 0x1ce90, 0x1ce9e,
- 0x1cea0, 0x1cebc, 0x1cecc, 0x1cef2, 0x1cef4, 0x1cf2e, 0x1cf32, 0x1cf34, 0x1cf4e, 0x1cf5c, 0x1cf62, 0x1cf64,
- 0x1cf68, 0x1cf96, 0x1cfa6, 0x1cfac, 0x1cfca, 0x1cfd2, 0x1cfd4, 0x1d02e, 0x1d032, 0x1d034, 0x1d04e, 0x1d05c,
- 0x1d062, 0x1d064, 0x1d068, 0x1d076, 0x1d08e, 0x1d09c, 0x1d0b8, 0x1d0c2, 0x1d0c4, 0x1d0c8, 0x1d0d0, 0x1d0de,
- 0x1d0e6, 0x1d0ec, 0x1d0fa, 0x1d11c, 0x1d138, 0x1d170, 0x1d17e, 0x1d182, 0x1d184, 0x1d188, 0x1d190, 0x1d19e,
- 0x1d1a0, 0x1d1bc, 0x1d1c6, 0x1d1cc, 0x1d1d8, 0x1d1ee, 0x1d1f2, 0x1d1f4, 0x1d21c, 0x1d238, 0x1d270, 0x1d27e,
- 0x1d2e0, 0x1d2fc, 0x1d302, 0x1d304, 0x1d308, 0x1d310, 0x1d31e, 0x1d320, 0x1d33c, 0x1d340, 0x1d378, 0x1d386,
- 0x1d38c, 0x1d398, 0x1d3b0, 0x1d3be, 0x1d3ce, 0x1d3dc, 0x1d3e2, 0x1d3e4, 0x1d3e8, 0x1d3f6, 0x1d470, 0x1d47e,
- 0x1d4e0, 0x1d4fc, 0x1d5c0, 0x1d5f8, 0x1d604, 0x1d608, 0x1d610, 0x1d620, 0x1d640, 0x1d678, 0x1d6f0, 0x1d706,
- 0x1d70c, 0x1d718, 0x1d730, 0x1d73e, 0x1d760, 0x1d77c, 0x1d78e, 0x1d79c, 0x1d7b8, 0x1d7c2, 0x1d7c4, 0x1d7c8,
- 0x1d7d0, 0x1d7de, 0x1d7e6, 0x1d7ec, 0x1d826, 0x1d82c, 0x1d83a, 0x1d846, 0x1d84c, 0x1d858, 0x1d872, 0x1d874,
- 0x1d886, 0x1d88c, 0x1d898, 0x1d8b0, 0x1d8be, 0x1d8ce, 0x1d8e2, 0x1d8e4, 0x1d8e8, 0x1d8f6, 0x1d90c, 0x1d918,
- 0x1d930, 0x1d93e, 0x1d960, 0x1d97c, 0x1d99c, 0x1d9c2, 0x1d9c4, 0x1d9c8, 0x1d9d0, 0x1d9e6, 0x1d9fa, 0x1da0c,
- 0x1da18, 0x1da30, 0x1da3e, 0x1da60, 0x1da7c, 0x1dac0, 0x1daf8, 0x1db38, 0x1db82, 0x1db84, 0x1db88, 0x1db90,
- 0x1db9e, 0x1dba0, 0x1dbcc, 0x1dbf2, 0x1dbf4, 0x1dc22, 0x1dc42, 0x1dc44, 0x1dc48, 0x1dc50, 0x1dc5e, 0x1dc66,
- 0x1dc7a, 0x1dc82, 0x1dc84, 0x1dc88, 0x1dc90, 0x1dc9e, 0x1dca0, 0x1dcbc, 0x1dccc, 0x1dcf2, 0x1dcf4, 0x1dd04,
- 0x1dd08, 0x1dd10, 0x1dd1e, 0x1dd20, 0x1dd3c, 0x1dd40, 0x1dd78, 0x1dd86, 0x1dd98, 0x1ddce, 0x1dde2, 0x1dde4,
- 0x1dde8, 0x1de2e, 0x1de32, 0x1de34, 0x1de4e, 0x1de5c, 0x1de62, 0x1de64, 0x1de68, 0x1de8e, 0x1de9c, 0x1deb8,
- 0x1dec2, 0x1dec4, 0x1dec8, 0x1ded0, 0x1dee6, 0x1defa, 0x1df16, 0x1df26, 0x1df2c, 0x1df46, 0x1df4c, 0x1df58,
- 0x1df72, 0x1df74, 0x1df8a, 0x1df92, 0x1df94, 0x1dfa2, 0x1dfa4, 0x1dfa8, 0x1e08a, 0x1e092, 0x1e094, 0x1e0a2,
- 0x1e0a4, 0x1e0a8, 0x1e0b6, 0x1e0da, 0x1e10a, 0x1e112, 0x1e114, 0x1e122, 0x1e124, 0x1e128, 0x1e136, 0x1e142,
- 0x1e144, 0x1e148, 0x1e150, 0x1e166, 0x1e16c, 0x1e17a, 0x1e19a, 0x1e1b2, 0x1e1b4, 0x1e20a, 0x1e212, 0x1e214,
- 0x1e222, 0x1e224, 0x1e228, 0x1e236, 0x1e242, 0x1e248, 0x1e250, 0x1e25e, 0x1e266, 0x1e26c, 0x1e27a, 0x1e282,
- 0x1e284, 0x1e288, 0x1e290, 0x1e2a0, 0x1e2bc, 0x1e2c6, 0x1e2cc, 0x1e2d8, 0x1e2ee, 0x1e2f2, 0x1e2f4, 0x1e31a,
- 0x1e332, 0x1e334, 0x1e35c, 0x1e362, 0x1e364, 0x1e368, 0x1e3ba, 0x1e40a, 0x1e412, 0x1e414, 0x1e422, 0x1e428,
- 0x1e436, 0x1e442, 0x1e448, 0x1e450, 0x1e45e, 0x1e466, 0x1e46c, 0x1e47a, 0x1e482, 0x1e484, 0x1e490, 0x1e49e,
- 0x1e4a0, 0x1e4bc, 0x1e4c6, 0x1e4cc, 0x1e4d8, 0x1e4ee, 0x1e4f2, 0x1e4f4, 0x1e502, 0x1e504, 0x1e508, 0x1e510,
- 0x1e51e, 0x1e520, 0x1e53c, 0x1e540, 0x1e578, 0x1e586, 0x1e58c, 0x1e598, 0x1e5b0, 0x1e5be, 0x1e5ce, 0x1e5dc,
- 0x1e5e2, 0x1e5e4, 0x1e5e8, 0x1e5f6, 0x1e61a, 0x1e62e, 0x1e632, 0x1e634, 0x1e64e, 0x1e65c, 0x1e662, 0x1e668,
- 0x1e68e, 0x1e69c, 0x1e6b8, 0x1e6c2, 0x1e6c4, 0x1e6c8, 0x1e6d0, 0x1e6e6, 0x1e6fa, 0x1e716, 0x1e726, 0x1e72c,
- 0x1e73a, 0x1e746, 0x1e74c, 0x1e758, 0x1e772, 0x1e774, 0x1e792, 0x1e794, 0x1e7a2, 0x1e7a4, 0x1e7a8, 0x1e7b6,
- 0x1e812, 0x1e814, 0x1e822, 0x1e824, 0x1e828, 0x1e836, 0x1e842, 0x1e844, 0x1e848, 0x1e850, 0x1e85e, 0x1e866,
- 0x1e86c, 0x1e87a, 0x1e882, 0x1e884, 0x1e888, 0x1e890, 0x1e89e, 0x1e8a0, 0x1e8bc, 0x1e8c6, 0x1e8cc, 0x1e8d8,
- 0x1e8ee, 0x1e8f2, 0x1e8f4, 0x1e902, 0x1e904, 0x1e908, 0x1e910, 0x1e920, 0x1e93c, 0x1e940, 0x1e978, 0x1e986,
- 0x1e98c, 0x1e998, 0x1e9b0, 0x1e9be, 0x1e9ce, 0x1e9dc, 0x1e9e2, 0x1e9e4, 0x1e9e8, 0x1e9f6, 0x1ea04, 0x1ea08,
- 0x1ea10, 0x1ea20, 0x1ea40, 0x1ea78, 0x1eaf0, 0x1eb06, 0x1eb0c, 0x1eb18, 0x1eb30, 0x1eb3e, 0x1eb60, 0x1eb7c,
- 0x1eb8e, 0x1eb9c, 0x1ebb8, 0x1ebc2, 0x1ebc4, 0x1ebc8, 0x1ebd0, 0x1ebde, 0x1ebe6, 0x1ebec, 0x1ec1a, 0x1ec2e,
- 0x1ec32, 0x1ec34, 0x1ec4e, 0x1ec5c, 0x1ec62, 0x1ec64, 0x1ec68, 0x1ec8e, 0x1ec9c, 0x1ecb8, 0x1ecc2, 0x1ecc4,
- 0x1ecc8, 0x1ecd0, 0x1ece6, 0x1ecfa, 0x1ed0e, 0x1ed1c, 0x1ed38, 0x1ed70, 0x1ed7e, 0x1ed82, 0x1ed84, 0x1ed88,
- 0x1ed90, 0x1ed9e, 0x1eda0, 0x1edcc, 0x1edf2, 0x1edf4, 0x1ee16, 0x1ee26, 0x1ee2c, 0x1ee3a, 0x1ee46, 0x1ee4c,
- 0x1ee58, 0x1ee6e, 0x1ee72, 0x1ee74, 0x1ee86, 0x1ee8c, 0x1ee98, 0x1eeb0, 0x1eebe, 0x1eece, 0x1eedc, 0x1eee2,
- 0x1eee4, 0x1eee8, 0x1ef12, 0x1ef22, 0x1ef24, 0x1ef28, 0x1ef36, 0x1ef42, 0x1ef44, 0x1ef48, 0x1ef50, 0x1ef5e,
- 0x1ef66, 0x1ef6c, 0x1ef7a, 0x1efae, 0x1efb2, 0x1efb4, 0x1efd6, 0x1f096, 0x1f0a6, 0x1f0ac, 0x1f0ba, 0x1f0ca,
- 0x1f0d2, 0x1f0d4, 0x1f116, 0x1f126, 0x1f12c, 0x1f13a, 0x1f146, 0x1f14c, 0x1f158, 0x1f16e, 0x1f172, 0x1f174,
- 0x1f18a, 0x1f192, 0x1f194, 0x1f1a2, 0x1f1a4, 0x1f1a8, 0x1f1da, 0x1f216, 0x1f226, 0x1f22c, 0x1f23a, 0x1f246,
- 0x1f258, 0x1f26e, 0x1f272, 0x1f274, 0x1f286, 0x1f28c, 0x1f298, 0x1f2b0, 0x1f2be, 0x1f2ce, 0x1f2dc, 0x1f2e2,
- 0x1f2e4, 0x1f2e8, 0x1f2f6, 0x1f30a, 0x1f312, 0x1f314, 0x1f322, 0x1f328, 0x1f342, 0x1f344, 0x1f348, 0x1f350,
- 0x1f35e, 0x1f366, 0x1f37a, 0x1f39a, 0x1f3ae, 0x1f3b2, 0x1f3b4, 0x1f416, 0x1f426, 0x1f42c, 0x1f43a, 0x1f446,
- 0x1f44c, 0x1f458, 0x1f46e, 0x1f472, 0x1f474, 0x1f486, 0x1f48c, 0x1f498, 0x1f4b0, 0x1f4be, 0x1f4ce, 0x1f4dc,
- 0x1f4e2, 0x1f4e4, 0x1f4e8, 0x1f4f6, 0x1f506, 0x1f50c, 0x1f518, 0x1f530, 0x1f53e, 0x1f560, 0x1f57c, 0x1f58e,
- 0x1f59c, 0x1f5b8, 0x1f5c2, 0x1f5c4, 0x1f5c8, 0x1f5d0, 0x1f5de, 0x1f5e6, 0x1f5ec, 0x1f5fa, 0x1f60a, 0x1f612,
- 0x1f614, 0x1f622, 0x1f624, 0x1f628, 0x1f636, 0x1f642, 0x1f644, 0x1f648, 0x1f650, 0x1f65e, 0x1f666, 0x1f67a,
- 0x1f682, 0x1f684, 0x1f688, 0x1f690, 0x1f69e, 0x1f6a0, 0x1f6bc, 0x1f6cc, 0x1f6f2, 0x1f6f4, 0x1f71a, 0x1f72e,
- 0x1f732, 0x1f734, 0x1f74e, 0x1f75c, 0x1f762, 0x1f764, 0x1f768, 0x1f776, 0x1f796, 0x1f7a6, 0x1f7ac, 0x1f7ba,
- 0x1f7d2, 0x1f7d4, 0x1f89a, 0x1f8ae, 0x1f8b2, 0x1f8b4, 0x1f8d6, 0x1f8ea, 0x1f91a, 0x1f92e, 0x1f932, 0x1f934,
- 0x1f94e, 0x1f95c, 0x1f962, 0x1f964, 0x1f968, 0x1f976, 0x1f996, 0x1f9a6, 0x1f9ac, 0x1f9ba, 0x1f9ca, 0x1f9d2,
- 0x1f9d4, 0x1fa1a, 0x1fa2e, 0x1fa32, 0x1fa34, 0x1fa4e, 0x1fa5c, 0x1fa62, 0x1fa64, 0x1fa68, 0x1fa76, 0x1fa8e,
- 0x1fa9c, 0x1fab8, 0x1fac2, 0x1fac4, 0x1fac8, 0x1fad0, 0x1fade, 0x1fae6, 0x1faec, 0x1fb16, 0x1fb26, 0x1fb2c,
- 0x1fb3a, 0x1fb46, 0x1fb4c, 0x1fb58, 0x1fb6e, 0x1fb72, 0x1fb74, 0x1fb8a, 0x1fb92, 0x1fb94, 0x1fba2, 0x1fba4,
- 0x1fba8, 0x1fbb6, 0x1fbda]);
+ /**
+ * The sorted table of all possible symbols. Extracted from the PDF417
+ * specification. The index of a symbol in this table corresponds to the
+ * index into the codeword table.
+ */
+ public static /* final int[] */ SYMBOL_TABLE = Int32Array.from([
+ 0x1025e, 0x1027a, 0x1029e, 0x102bc, 0x102f2, 0x102f4, 0x1032e, 0x1034e, 0x1035c, 0x10396, 0x103a6, 0x103ac,
+ 0x10422, 0x10428, 0x10436, 0x10442, 0x10444, 0x10448, 0x10450, 0x1045e, 0x10466, 0x1046c, 0x1047a, 0x10482,
+ 0x1049e, 0x104a0, 0x104bc, 0x104c6, 0x104d8, 0x104ee, 0x104f2, 0x104f4, 0x10504, 0x10508, 0x10510, 0x1051e,
+ 0x10520, 0x1053c, 0x10540, 0x10578, 0x10586, 0x1058c, 0x10598, 0x105b0, 0x105be, 0x105ce, 0x105dc, 0x105e2,
+ 0x105e4, 0x105e8, 0x105f6, 0x1062e, 0x1064e, 0x1065c, 0x1068e, 0x1069c, 0x106b8, 0x106de, 0x106fa, 0x10716,
+ 0x10726, 0x1072c, 0x10746, 0x1074c, 0x10758, 0x1076e, 0x10792, 0x10794, 0x107a2, 0x107a4, 0x107a8, 0x107b6,
+ 0x10822, 0x10828, 0x10842, 0x10848, 0x10850, 0x1085e, 0x10866, 0x1086c, 0x1087a, 0x10882, 0x10884, 0x10890,
+ 0x1089e, 0x108a0, 0x108bc, 0x108c6, 0x108cc, 0x108d8, 0x108ee, 0x108f2, 0x108f4, 0x10902, 0x10908, 0x1091e,
+ 0x10920, 0x1093c, 0x10940, 0x10978, 0x10986, 0x10998, 0x109b0, 0x109be, 0x109ce, 0x109dc, 0x109e2, 0x109e4,
+ 0x109e8, 0x109f6, 0x10a08, 0x10a10, 0x10a1e, 0x10a20, 0x10a3c, 0x10a40, 0x10a78, 0x10af0, 0x10b06, 0x10b0c,
+ 0x10b18, 0x10b30, 0x10b3e, 0x10b60, 0x10b7c, 0x10b8e, 0x10b9c, 0x10bb8, 0x10bc2, 0x10bc4, 0x10bc8, 0x10bd0,
+ 0x10bde, 0x10be6, 0x10bec, 0x10c2e, 0x10c4e, 0x10c5c, 0x10c62, 0x10c64, 0x10c68, 0x10c76, 0x10c8e, 0x10c9c,
+ 0x10cb8, 0x10cc2, 0x10cc4, 0x10cc8, 0x10cd0, 0x10cde, 0x10ce6, 0x10cec, 0x10cfa, 0x10d0e, 0x10d1c, 0x10d38,
+ 0x10d70, 0x10d7e, 0x10d82, 0x10d84, 0x10d88, 0x10d90, 0x10d9e, 0x10da0, 0x10dbc, 0x10dc6, 0x10dcc, 0x10dd8,
+ 0x10dee, 0x10df2, 0x10df4, 0x10e16, 0x10e26, 0x10e2c, 0x10e46, 0x10e58, 0x10e6e, 0x10e86, 0x10e8c, 0x10e98,
+ 0x10eb0, 0x10ebe, 0x10ece, 0x10edc, 0x10f0a, 0x10f12, 0x10f14, 0x10f22, 0x10f28, 0x10f36, 0x10f42, 0x10f44,
+ 0x10f48, 0x10f50, 0x10f5e, 0x10f66, 0x10f6c, 0x10fb2, 0x10fb4, 0x11022, 0x11028, 0x11042, 0x11048, 0x11050,
+ 0x1105e, 0x1107a, 0x11082, 0x11084, 0x11090, 0x1109e, 0x110a0, 0x110bc, 0x110c6, 0x110cc, 0x110d8, 0x110ee,
+ 0x110f2, 0x110f4, 0x11102, 0x1111e, 0x11120, 0x1113c, 0x11140, 0x11178, 0x11186, 0x11198, 0x111b0, 0x111be,
+ 0x111ce, 0x111dc, 0x111e2, 0x111e4, 0x111e8, 0x111f6, 0x11208, 0x1121e, 0x11220, 0x11278, 0x112f0, 0x1130c,
+ 0x11330, 0x1133e, 0x11360, 0x1137c, 0x1138e, 0x1139c, 0x113b8, 0x113c2, 0x113c8, 0x113d0, 0x113de, 0x113e6,
+ 0x113ec, 0x11408, 0x11410, 0x1141e, 0x11420, 0x1143c, 0x11440, 0x11478, 0x114f0, 0x115e0, 0x1160c, 0x11618,
+ 0x11630, 0x1163e, 0x11660, 0x1167c, 0x116c0, 0x116f8, 0x1171c, 0x11738, 0x11770, 0x1177e, 0x11782, 0x11784,
+ 0x11788, 0x11790, 0x1179e, 0x117a0, 0x117bc, 0x117c6, 0x117cc, 0x117d8, 0x117ee, 0x1182e, 0x11834, 0x1184e,
+ 0x1185c, 0x11862, 0x11864, 0x11868, 0x11876, 0x1188e, 0x1189c, 0x118b8, 0x118c2, 0x118c8, 0x118d0, 0x118de,
+ 0x118e6, 0x118ec, 0x118fa, 0x1190e, 0x1191c, 0x11938, 0x11970, 0x1197e, 0x11982, 0x11984, 0x11990, 0x1199e,
+ 0x119a0, 0x119bc, 0x119c6, 0x119cc, 0x119d8, 0x119ee, 0x119f2, 0x119f4, 0x11a0e, 0x11a1c, 0x11a38, 0x11a70,
+ 0x11a7e, 0x11ae0, 0x11afc, 0x11b08, 0x11b10, 0x11b1e, 0x11b20, 0x11b3c, 0x11b40, 0x11b78, 0x11b8c, 0x11b98,
+ 0x11bb0, 0x11bbe, 0x11bce, 0x11bdc, 0x11be2, 0x11be4, 0x11be8, 0x11bf6, 0x11c16, 0x11c26, 0x11c2c, 0x11c46,
+ 0x11c4c, 0x11c58, 0x11c6e, 0x11c86, 0x11c98, 0x11cb0, 0x11cbe, 0x11cce, 0x11cdc, 0x11ce2, 0x11ce4, 0x11ce8,
+ 0x11cf6, 0x11d06, 0x11d0c, 0x11d18, 0x11d30, 0x11d3e, 0x11d60, 0x11d7c, 0x11d8e, 0x11d9c, 0x11db8, 0x11dc4,
+ 0x11dc8, 0x11dd0, 0x11dde, 0x11de6, 0x11dec, 0x11dfa, 0x11e0a, 0x11e12, 0x11e14, 0x11e22, 0x11e24, 0x11e28,
+ 0x11e36, 0x11e42, 0x11e44, 0x11e50, 0x11e5e, 0x11e66, 0x11e6c, 0x11e82, 0x11e84, 0x11e88, 0x11e90, 0x11e9e,
+ 0x11ea0, 0x11ebc, 0x11ec6, 0x11ecc, 0x11ed8, 0x11eee, 0x11f1a, 0x11f2e, 0x11f32, 0x11f34, 0x11f4e, 0x11f5c,
+ 0x11f62, 0x11f64, 0x11f68, 0x11f76, 0x12048, 0x1205e, 0x12082, 0x12084, 0x12090, 0x1209e, 0x120a0, 0x120bc,
+ 0x120d8, 0x120f2, 0x120f4, 0x12108, 0x1211e, 0x12120, 0x1213c, 0x12140, 0x12178, 0x12186, 0x12198, 0x121b0,
+ 0x121be, 0x121e2, 0x121e4, 0x121e8, 0x121f6, 0x12204, 0x12210, 0x1221e, 0x12220, 0x12278, 0x122f0, 0x12306,
+ 0x1230c, 0x12330, 0x1233e, 0x12360, 0x1237c, 0x1238e, 0x1239c, 0x123b8, 0x123c2, 0x123c8, 0x123d0, 0x123e6,
+ 0x123ec, 0x1241e, 0x12420, 0x1243c, 0x124f0, 0x125e0, 0x12618, 0x1263e, 0x12660, 0x1267c, 0x126c0, 0x126f8,
+ 0x12738, 0x12770, 0x1277e, 0x12782, 0x12784, 0x12790, 0x1279e, 0x127a0, 0x127bc, 0x127c6, 0x127cc, 0x127d8,
+ 0x127ee, 0x12820, 0x1283c, 0x12840, 0x12878, 0x128f0, 0x129e0, 0x12bc0, 0x12c18, 0x12c30, 0x12c3e, 0x12c60,
+ 0x12c7c, 0x12cc0, 0x12cf8, 0x12df0, 0x12e1c, 0x12e38, 0x12e70, 0x12e7e, 0x12ee0, 0x12efc, 0x12f04, 0x12f08,
+ 0x12f10, 0x12f20, 0x12f3c, 0x12f40, 0x12f78, 0x12f86, 0x12f8c, 0x12f98, 0x12fb0, 0x12fbe, 0x12fce, 0x12fdc,
+ 0x1302e, 0x1304e, 0x1305c, 0x13062, 0x13068, 0x1308e, 0x1309c, 0x130b8, 0x130c2, 0x130c8, 0x130d0, 0x130de,
+ 0x130ec, 0x130fa, 0x1310e, 0x13138, 0x13170, 0x1317e, 0x13182, 0x13184, 0x13190, 0x1319e, 0x131a0, 0x131bc,
+ 0x131c6, 0x131cc, 0x131d8, 0x131f2, 0x131f4, 0x1320e, 0x1321c, 0x13270, 0x1327e, 0x132e0, 0x132fc, 0x13308,
+ 0x1331e, 0x13320, 0x1333c, 0x13340, 0x13378, 0x13386, 0x13398, 0x133b0, 0x133be, 0x133ce, 0x133dc, 0x133e2,
+ 0x133e4, 0x133e8, 0x133f6, 0x1340e, 0x1341c, 0x13438, 0x13470, 0x1347e, 0x134e0, 0x134fc, 0x135c0, 0x135f8,
+ 0x13608, 0x13610, 0x1361e, 0x13620, 0x1363c, 0x13640, 0x13678, 0x136f0, 0x1370c, 0x13718, 0x13730, 0x1373e,
+ 0x13760, 0x1377c, 0x1379c, 0x137b8, 0x137c2, 0x137c4, 0x137c8, 0x137d0, 0x137de, 0x137e6, 0x137ec, 0x13816,
+ 0x13826, 0x1382c, 0x13846, 0x1384c, 0x13858, 0x1386e, 0x13874, 0x13886, 0x13898, 0x138b0, 0x138be, 0x138ce,
+ 0x138dc, 0x138e2, 0x138e4, 0x138e8, 0x13906, 0x1390c, 0x13930, 0x1393e, 0x13960, 0x1397c, 0x1398e, 0x1399c,
+ 0x139b8, 0x139c8, 0x139d0, 0x139de, 0x139e6, 0x139ec, 0x139fa, 0x13a06, 0x13a0c, 0x13a18, 0x13a30, 0x13a3e,
+ 0x13a60, 0x13a7c, 0x13ac0, 0x13af8, 0x13b0e, 0x13b1c, 0x13b38, 0x13b70, 0x13b7e, 0x13b88, 0x13b90, 0x13b9e,
+ 0x13ba0, 0x13bbc, 0x13bcc, 0x13bd8, 0x13bee, 0x13bf2, 0x13bf4, 0x13c12, 0x13c14, 0x13c22, 0x13c24, 0x13c28,
+ 0x13c36, 0x13c42, 0x13c48, 0x13c50, 0x13c5e, 0x13c66, 0x13c6c, 0x13c82, 0x13c84, 0x13c90, 0x13c9e, 0x13ca0,
+ 0x13cbc, 0x13cc6, 0x13ccc, 0x13cd8, 0x13cee, 0x13d02, 0x13d04, 0x13d08, 0x13d10, 0x13d1e, 0x13d20, 0x13d3c,
+ 0x13d40, 0x13d78, 0x13d86, 0x13d8c, 0x13d98, 0x13db0, 0x13dbe, 0x13dce, 0x13ddc, 0x13de4, 0x13de8, 0x13df6,
+ 0x13e1a, 0x13e2e, 0x13e32, 0x13e34, 0x13e4e, 0x13e5c, 0x13e62, 0x13e64, 0x13e68, 0x13e76, 0x13e8e, 0x13e9c,
+ 0x13eb8, 0x13ec2, 0x13ec4, 0x13ec8, 0x13ed0, 0x13ede, 0x13ee6, 0x13eec, 0x13f26, 0x13f2c, 0x13f3a, 0x13f46,
+ 0x13f4c, 0x13f58, 0x13f6e, 0x13f72, 0x13f74, 0x14082, 0x1409e, 0x140a0, 0x140bc, 0x14104, 0x14108, 0x14110,
+ 0x1411e, 0x14120, 0x1413c, 0x14140, 0x14178, 0x1418c, 0x14198, 0x141b0, 0x141be, 0x141e2, 0x141e4, 0x141e8,
+ 0x14208, 0x14210, 0x1421e, 0x14220, 0x1423c, 0x14240, 0x14278, 0x142f0, 0x14306, 0x1430c, 0x14318, 0x14330,
+ 0x1433e, 0x14360, 0x1437c, 0x1438e, 0x143c2, 0x143c4, 0x143c8, 0x143d0, 0x143e6, 0x143ec, 0x14408, 0x14410,
+ 0x1441e, 0x14420, 0x1443c, 0x14440, 0x14478, 0x144f0, 0x145e0, 0x1460c, 0x14618, 0x14630, 0x1463e, 0x14660,
+ 0x1467c, 0x146c0, 0x146f8, 0x1471c, 0x14738, 0x14770, 0x1477e, 0x14782, 0x14784, 0x14788, 0x14790, 0x147a0,
+ 0x147bc, 0x147c6, 0x147cc, 0x147d8, 0x147ee, 0x14810, 0x14820, 0x1483c, 0x14840, 0x14878, 0x148f0, 0x149e0,
+ 0x14bc0, 0x14c30, 0x14c3e, 0x14c60, 0x14c7c, 0x14cc0, 0x14cf8, 0x14df0, 0x14e38, 0x14e70, 0x14e7e, 0x14ee0,
+ 0x14efc, 0x14f04, 0x14f08, 0x14f10, 0x14f1e, 0x14f20, 0x14f3c, 0x14f40, 0x14f78, 0x14f86, 0x14f8c, 0x14f98,
+ 0x14fb0, 0x14fce, 0x14fdc, 0x15020, 0x15040, 0x15078, 0x150f0, 0x151e0, 0x153c0, 0x15860, 0x1587c, 0x158c0,
+ 0x158f8, 0x159f0, 0x15be0, 0x15c70, 0x15c7e, 0x15ce0, 0x15cfc, 0x15dc0, 0x15df8, 0x15e08, 0x15e10, 0x15e20,
+ 0x15e40, 0x15e78, 0x15ef0, 0x15f0c, 0x15f18, 0x15f30, 0x15f60, 0x15f7c, 0x15f8e, 0x15f9c, 0x15fb8, 0x1604e,
+ 0x1605c, 0x1608e, 0x1609c, 0x160b8, 0x160c2, 0x160c4, 0x160c8, 0x160de, 0x1610e, 0x1611c, 0x16138, 0x16170,
+ 0x1617e, 0x16184, 0x16188, 0x16190, 0x1619e, 0x161a0, 0x161bc, 0x161c6, 0x161cc, 0x161d8, 0x161f2, 0x161f4,
+ 0x1620e, 0x1621c, 0x16238, 0x16270, 0x1627e, 0x162e0, 0x162fc, 0x16304, 0x16308, 0x16310, 0x1631e, 0x16320,
+ 0x1633c, 0x16340, 0x16378, 0x16386, 0x1638c, 0x16398, 0x163b0, 0x163be, 0x163ce, 0x163dc, 0x163e2, 0x163e4,
+ 0x163e8, 0x163f6, 0x1640e, 0x1641c, 0x16438, 0x16470, 0x1647e, 0x164e0, 0x164fc, 0x165c0, 0x165f8, 0x16610,
+ 0x1661e, 0x16620, 0x1663c, 0x16640, 0x16678, 0x166f0, 0x16718, 0x16730, 0x1673e, 0x16760, 0x1677c, 0x1678e,
+ 0x1679c, 0x167b8, 0x167c2, 0x167c4, 0x167c8, 0x167d0, 0x167de, 0x167e6, 0x167ec, 0x1681c, 0x16838, 0x16870,
+ 0x168e0, 0x168fc, 0x169c0, 0x169f8, 0x16bf0, 0x16c10, 0x16c1e, 0x16c20, 0x16c3c, 0x16c40, 0x16c78, 0x16cf0,
+ 0x16de0, 0x16e18, 0x16e30, 0x16e3e, 0x16e60, 0x16e7c, 0x16ec0, 0x16ef8, 0x16f1c, 0x16f38, 0x16f70, 0x16f7e,
+ 0x16f84, 0x16f88, 0x16f90, 0x16f9e, 0x16fa0, 0x16fbc, 0x16fc6, 0x16fcc, 0x16fd8, 0x17026, 0x1702c, 0x17046,
+ 0x1704c, 0x17058, 0x1706e, 0x17086, 0x1708c, 0x17098, 0x170b0, 0x170be, 0x170ce, 0x170dc, 0x170e8, 0x17106,
+ 0x1710c, 0x17118, 0x17130, 0x1713e, 0x17160, 0x1717c, 0x1718e, 0x1719c, 0x171b8, 0x171c2, 0x171c4, 0x171c8,
+ 0x171d0, 0x171de, 0x171e6, 0x171ec, 0x171fa, 0x17206, 0x1720c, 0x17218, 0x17230, 0x1723e, 0x17260, 0x1727c,
+ 0x172c0, 0x172f8, 0x1730e, 0x1731c, 0x17338, 0x17370, 0x1737e, 0x17388, 0x17390, 0x1739e, 0x173a0, 0x173bc,
+ 0x173cc, 0x173d8, 0x173ee, 0x173f2, 0x173f4, 0x1740c, 0x17418, 0x17430, 0x1743e, 0x17460, 0x1747c, 0x174c0,
+ 0x174f8, 0x175f0, 0x1760e, 0x1761c, 0x17638, 0x17670, 0x1767e, 0x176e0, 0x176fc, 0x17708, 0x17710, 0x1771e,
+ 0x17720, 0x1773c, 0x17740, 0x17778, 0x17798, 0x177b0, 0x177be, 0x177dc, 0x177e2, 0x177e4, 0x177e8, 0x17822,
+ 0x17824, 0x17828, 0x17836, 0x17842, 0x17844, 0x17848, 0x17850, 0x1785e, 0x17866, 0x1786c, 0x17882, 0x17884,
+ 0x17888, 0x17890, 0x1789e, 0x178a0, 0x178bc, 0x178c6, 0x178cc, 0x178d8, 0x178ee, 0x178f2, 0x178f4, 0x17902,
+ 0x17904, 0x17908, 0x17910, 0x1791e, 0x17920, 0x1793c, 0x17940, 0x17978, 0x17986, 0x1798c, 0x17998, 0x179b0,
+ 0x179be, 0x179ce, 0x179dc, 0x179e2, 0x179e4, 0x179e8, 0x179f6, 0x17a04, 0x17a08, 0x17a10, 0x17a1e, 0x17a20,
+ 0x17a3c, 0x17a40, 0x17a78, 0x17af0, 0x17b06, 0x17b0c, 0x17b18, 0x17b30, 0x17b3e, 0x17b60, 0x17b7c, 0x17b8e,
+ 0x17b9c, 0x17bb8, 0x17bc4, 0x17bc8, 0x17bd0, 0x17bde, 0x17be6, 0x17bec, 0x17c2e, 0x17c32, 0x17c34, 0x17c4e,
+ 0x17c5c, 0x17c62, 0x17c64, 0x17c68, 0x17c76, 0x17c8e, 0x17c9c, 0x17cb8, 0x17cc2, 0x17cc4, 0x17cc8, 0x17cd0,
+ 0x17cde, 0x17ce6, 0x17cec, 0x17d0e, 0x17d1c, 0x17d38, 0x17d70, 0x17d82, 0x17d84, 0x17d88, 0x17d90, 0x17d9e,
+ 0x17da0, 0x17dbc, 0x17dc6, 0x17dcc, 0x17dd8, 0x17dee, 0x17e26, 0x17e2c, 0x17e3a, 0x17e46, 0x17e4c, 0x17e58,
+ 0x17e6e, 0x17e72, 0x17e74, 0x17e86, 0x17e8c, 0x17e98, 0x17eb0, 0x17ece, 0x17edc, 0x17ee2, 0x17ee4, 0x17ee8,
+ 0x17ef6, 0x1813a, 0x18172, 0x18174, 0x18216, 0x18226, 0x1823a, 0x1824c, 0x18258, 0x1826e, 0x18272, 0x18274,
+ 0x18298, 0x182be, 0x182e2, 0x182e4, 0x182e8, 0x182f6, 0x1835e, 0x1837a, 0x183ae, 0x183d6, 0x18416, 0x18426,
+ 0x1842c, 0x1843a, 0x18446, 0x18458, 0x1846e, 0x18472, 0x18474, 0x18486, 0x184b0, 0x184be, 0x184ce, 0x184dc,
+ 0x184e2, 0x184e4, 0x184e8, 0x184f6, 0x18506, 0x1850c, 0x18518, 0x18530, 0x1853e, 0x18560, 0x1857c, 0x1858e,
+ 0x1859c, 0x185b8, 0x185c2, 0x185c4, 0x185c8, 0x185d0, 0x185de, 0x185e6, 0x185ec, 0x185fa, 0x18612, 0x18614,
+ 0x18622, 0x18628, 0x18636, 0x18642, 0x18650, 0x1865e, 0x1867a, 0x18682, 0x18684, 0x18688, 0x18690, 0x1869e,
+ 0x186a0, 0x186bc, 0x186c6, 0x186cc, 0x186d8, 0x186ee, 0x186f2, 0x186f4, 0x1872e, 0x1874e, 0x1875c, 0x18796,
+ 0x187a6, 0x187ac, 0x187d2, 0x187d4, 0x18826, 0x1882c, 0x1883a, 0x18846, 0x1884c, 0x18858, 0x1886e, 0x18872,
+ 0x18874, 0x18886, 0x18898, 0x188b0, 0x188be, 0x188ce, 0x188dc, 0x188e2, 0x188e4, 0x188e8, 0x188f6, 0x1890c,
+ 0x18930, 0x1893e, 0x18960, 0x1897c, 0x1898e, 0x189b8, 0x189c2, 0x189c8, 0x189d0, 0x189de, 0x189e6, 0x189ec,
+ 0x189fa, 0x18a18, 0x18a30, 0x18a3e, 0x18a60, 0x18a7c, 0x18ac0, 0x18af8, 0x18b1c, 0x18b38, 0x18b70, 0x18b7e,
+ 0x18b82, 0x18b84, 0x18b88, 0x18b90, 0x18b9e, 0x18ba0, 0x18bbc, 0x18bc6, 0x18bcc, 0x18bd8, 0x18bee, 0x18bf2,
+ 0x18bf4, 0x18c22, 0x18c24, 0x18c28, 0x18c36, 0x18c42, 0x18c48, 0x18c50, 0x18c5e, 0x18c66, 0x18c7a, 0x18c82,
+ 0x18c84, 0x18c90, 0x18c9e, 0x18ca0, 0x18cbc, 0x18ccc, 0x18cf2, 0x18cf4, 0x18d04, 0x18d08, 0x18d10, 0x18d1e,
+ 0x18d20, 0x18d3c, 0x18d40, 0x18d78, 0x18d86, 0x18d98, 0x18dce, 0x18de2, 0x18de4, 0x18de8, 0x18e2e, 0x18e32,
+ 0x18e34, 0x18e4e, 0x18e5c, 0x18e62, 0x18e64, 0x18e68, 0x18e8e, 0x18e9c, 0x18eb8, 0x18ec2, 0x18ec4, 0x18ec8,
+ 0x18ed0, 0x18efa, 0x18f16, 0x18f26, 0x18f2c, 0x18f46, 0x18f4c, 0x18f58, 0x18f6e, 0x18f8a, 0x18f92, 0x18f94,
+ 0x18fa2, 0x18fa4, 0x18fa8, 0x18fb6, 0x1902c, 0x1903a, 0x19046, 0x1904c, 0x19058, 0x19072, 0x19074, 0x19086,
+ 0x19098, 0x190b0, 0x190be, 0x190ce, 0x190dc, 0x190e2, 0x190e8, 0x190f6, 0x19106, 0x1910c, 0x19130, 0x1913e,
+ 0x19160, 0x1917c, 0x1918e, 0x1919c, 0x191b8, 0x191c2, 0x191c8, 0x191d0, 0x191de, 0x191e6, 0x191ec, 0x191fa,
+ 0x19218, 0x1923e, 0x19260, 0x1927c, 0x192c0, 0x192f8, 0x19338, 0x19370, 0x1937e, 0x19382, 0x19384, 0x19390,
+ 0x1939e, 0x193a0, 0x193bc, 0x193c6, 0x193cc, 0x193d8, 0x193ee, 0x193f2, 0x193f4, 0x19430, 0x1943e, 0x19460,
+ 0x1947c, 0x194c0, 0x194f8, 0x195f0, 0x19638, 0x19670, 0x1967e, 0x196e0, 0x196fc, 0x19702, 0x19704, 0x19708,
+ 0x19710, 0x19720, 0x1973c, 0x19740, 0x19778, 0x19786, 0x1978c, 0x19798, 0x197b0, 0x197be, 0x197ce, 0x197dc,
+ 0x197e2, 0x197e4, 0x197e8, 0x19822, 0x19824, 0x19842, 0x19848, 0x19850, 0x1985e, 0x19866, 0x1987a, 0x19882,
+ 0x19884, 0x19890, 0x1989e, 0x198a0, 0x198bc, 0x198cc, 0x198f2, 0x198f4, 0x19902, 0x19908, 0x1991e, 0x19920,
+ 0x1993c, 0x19940, 0x19978, 0x19986, 0x19998, 0x199ce, 0x199e2, 0x199e4, 0x199e8, 0x19a08, 0x19a10, 0x19a1e,
+ 0x19a20, 0x19a3c, 0x19a40, 0x19a78, 0x19af0, 0x19b18, 0x19b3e, 0x19b60, 0x19b9c, 0x19bc2, 0x19bc4, 0x19bc8,
+ 0x19bd0, 0x19be6, 0x19c2e, 0x19c34, 0x19c4e, 0x19c5c, 0x19c62, 0x19c64, 0x19c68, 0x19c8e, 0x19c9c, 0x19cb8,
+ 0x19cc2, 0x19cc8, 0x19cd0, 0x19ce6, 0x19cfa, 0x19d0e, 0x19d1c, 0x19d38, 0x19d70, 0x19d7e, 0x19d82, 0x19d84,
+ 0x19d88, 0x19d90, 0x19da0, 0x19dcc, 0x19df2, 0x19df4, 0x19e16, 0x19e26, 0x19e2c, 0x19e46, 0x19e4c, 0x19e58,
+ 0x19e74, 0x19e86, 0x19e8c, 0x19e98, 0x19eb0, 0x19ebe, 0x19ece, 0x19ee2, 0x19ee4, 0x19ee8, 0x19f0a, 0x19f12,
+ 0x19f14, 0x19f22, 0x19f24, 0x19f28, 0x19f42, 0x19f44, 0x19f48, 0x19f50, 0x19f5e, 0x19f6c, 0x19f9a, 0x19fae,
+ 0x19fb2, 0x19fb4, 0x1a046, 0x1a04c, 0x1a072, 0x1a074, 0x1a086, 0x1a08c, 0x1a098, 0x1a0b0, 0x1a0be, 0x1a0e2,
+ 0x1a0e4, 0x1a0e8, 0x1a0f6, 0x1a106, 0x1a10c, 0x1a118, 0x1a130, 0x1a13e, 0x1a160, 0x1a17c, 0x1a18e, 0x1a19c,
+ 0x1a1b8, 0x1a1c2, 0x1a1c4, 0x1a1c8, 0x1a1d0, 0x1a1de, 0x1a1e6, 0x1a1ec, 0x1a218, 0x1a230, 0x1a23e, 0x1a260,
+ 0x1a27c, 0x1a2c0, 0x1a2f8, 0x1a31c, 0x1a338, 0x1a370, 0x1a37e, 0x1a382, 0x1a384, 0x1a388, 0x1a390, 0x1a39e,
+ 0x1a3a0, 0x1a3bc, 0x1a3c6, 0x1a3cc, 0x1a3d8, 0x1a3ee, 0x1a3f2, 0x1a3f4, 0x1a418, 0x1a430, 0x1a43e, 0x1a460,
+ 0x1a47c, 0x1a4c0, 0x1a4f8, 0x1a5f0, 0x1a61c, 0x1a638, 0x1a670, 0x1a67e, 0x1a6e0, 0x1a6fc, 0x1a702, 0x1a704,
+ 0x1a708, 0x1a710, 0x1a71e, 0x1a720, 0x1a73c, 0x1a740, 0x1a778, 0x1a786, 0x1a78c, 0x1a798, 0x1a7b0, 0x1a7be,
+ 0x1a7ce, 0x1a7dc, 0x1a7e2, 0x1a7e4, 0x1a7e8, 0x1a830, 0x1a860, 0x1a87c, 0x1a8c0, 0x1a8f8, 0x1a9f0, 0x1abe0,
+ 0x1ac70, 0x1ac7e, 0x1ace0, 0x1acfc, 0x1adc0, 0x1adf8, 0x1ae04, 0x1ae08, 0x1ae10, 0x1ae20, 0x1ae3c, 0x1ae40,
+ 0x1ae78, 0x1aef0, 0x1af06, 0x1af0c, 0x1af18, 0x1af30, 0x1af3e, 0x1af60, 0x1af7c, 0x1af8e, 0x1af9c, 0x1afb8,
+ 0x1afc4, 0x1afc8, 0x1afd0, 0x1afde, 0x1b042, 0x1b05e, 0x1b07a, 0x1b082, 0x1b084, 0x1b088, 0x1b090, 0x1b09e,
+ 0x1b0a0, 0x1b0bc, 0x1b0cc, 0x1b0f2, 0x1b0f4, 0x1b102, 0x1b104, 0x1b108, 0x1b110, 0x1b11e, 0x1b120, 0x1b13c,
+ 0x1b140, 0x1b178, 0x1b186, 0x1b198, 0x1b1ce, 0x1b1e2, 0x1b1e4, 0x1b1e8, 0x1b204, 0x1b208, 0x1b210, 0x1b21e,
+ 0x1b220, 0x1b23c, 0x1b240, 0x1b278, 0x1b2f0, 0x1b30c, 0x1b33e, 0x1b360, 0x1b39c, 0x1b3c2, 0x1b3c4, 0x1b3c8,
+ 0x1b3d0, 0x1b3e6, 0x1b410, 0x1b41e, 0x1b420, 0x1b43c, 0x1b440, 0x1b478, 0x1b4f0, 0x1b5e0, 0x1b618, 0x1b660,
+ 0x1b67c, 0x1b6c0, 0x1b738, 0x1b782, 0x1b784, 0x1b788, 0x1b790, 0x1b79e, 0x1b7a0, 0x1b7cc, 0x1b82e, 0x1b84e,
+ 0x1b85c, 0x1b88e, 0x1b89c, 0x1b8b8, 0x1b8c2, 0x1b8c4, 0x1b8c8, 0x1b8d0, 0x1b8e6, 0x1b8fa, 0x1b90e, 0x1b91c,
+ 0x1b938, 0x1b970, 0x1b97e, 0x1b982, 0x1b984, 0x1b988, 0x1b990, 0x1b99e, 0x1b9a0, 0x1b9cc, 0x1b9f2, 0x1b9f4,
+ 0x1ba0e, 0x1ba1c, 0x1ba38, 0x1ba70, 0x1ba7e, 0x1bae0, 0x1bafc, 0x1bb08, 0x1bb10, 0x1bb20, 0x1bb3c, 0x1bb40,
+ 0x1bb98, 0x1bbce, 0x1bbe2, 0x1bbe4, 0x1bbe8, 0x1bc16, 0x1bc26, 0x1bc2c, 0x1bc46, 0x1bc4c, 0x1bc58, 0x1bc72,
+ 0x1bc74, 0x1bc86, 0x1bc8c, 0x1bc98, 0x1bcb0, 0x1bcbe, 0x1bcce, 0x1bce2, 0x1bce4, 0x1bce8, 0x1bd06, 0x1bd0c,
+ 0x1bd18, 0x1bd30, 0x1bd3e, 0x1bd60, 0x1bd7c, 0x1bd9c, 0x1bdc2, 0x1bdc4, 0x1bdc8, 0x1bdd0, 0x1bde6, 0x1bdfa,
+ 0x1be12, 0x1be14, 0x1be22, 0x1be24, 0x1be28, 0x1be42, 0x1be44, 0x1be48, 0x1be50, 0x1be5e, 0x1be66, 0x1be82,
+ 0x1be84, 0x1be88, 0x1be90, 0x1be9e, 0x1bea0, 0x1bebc, 0x1becc, 0x1bef4, 0x1bf1a, 0x1bf2e, 0x1bf32, 0x1bf34,
+ 0x1bf4e, 0x1bf5c, 0x1bf62, 0x1bf64, 0x1bf68, 0x1c09a, 0x1c0b2, 0x1c0b4, 0x1c11a, 0x1c132, 0x1c134, 0x1c162,
+ 0x1c164, 0x1c168, 0x1c176, 0x1c1ba, 0x1c21a, 0x1c232, 0x1c234, 0x1c24e, 0x1c25c, 0x1c262, 0x1c264, 0x1c268,
+ 0x1c276, 0x1c28e, 0x1c2c2, 0x1c2c4, 0x1c2c8, 0x1c2d0, 0x1c2de, 0x1c2e6, 0x1c2ec, 0x1c2fa, 0x1c316, 0x1c326,
+ 0x1c33a, 0x1c346, 0x1c34c, 0x1c372, 0x1c374, 0x1c41a, 0x1c42e, 0x1c432, 0x1c434, 0x1c44e, 0x1c45c, 0x1c462,
+ 0x1c464, 0x1c468, 0x1c476, 0x1c48e, 0x1c49c, 0x1c4b8, 0x1c4c2, 0x1c4c8, 0x1c4d0, 0x1c4de, 0x1c4e6, 0x1c4ec,
+ 0x1c4fa, 0x1c51c, 0x1c538, 0x1c570, 0x1c57e, 0x1c582, 0x1c584, 0x1c588, 0x1c590, 0x1c59e, 0x1c5a0, 0x1c5bc,
+ 0x1c5c6, 0x1c5cc, 0x1c5d8, 0x1c5ee, 0x1c5f2, 0x1c5f4, 0x1c616, 0x1c626, 0x1c62c, 0x1c63a, 0x1c646, 0x1c64c,
+ 0x1c658, 0x1c66e, 0x1c672, 0x1c674, 0x1c686, 0x1c68c, 0x1c698, 0x1c6b0, 0x1c6be, 0x1c6ce, 0x1c6dc, 0x1c6e2,
+ 0x1c6e4, 0x1c6e8, 0x1c712, 0x1c714, 0x1c722, 0x1c728, 0x1c736, 0x1c742, 0x1c744, 0x1c748, 0x1c750, 0x1c75e,
+ 0x1c766, 0x1c76c, 0x1c77a, 0x1c7ae, 0x1c7d6, 0x1c7ea, 0x1c81a, 0x1c82e, 0x1c832, 0x1c834, 0x1c84e, 0x1c85c,
+ 0x1c862, 0x1c864, 0x1c868, 0x1c876, 0x1c88e, 0x1c89c, 0x1c8b8, 0x1c8c2, 0x1c8c8, 0x1c8d0, 0x1c8de, 0x1c8e6,
+ 0x1c8ec, 0x1c8fa, 0x1c90e, 0x1c938, 0x1c970, 0x1c97e, 0x1c982, 0x1c984, 0x1c990, 0x1c99e, 0x1c9a0, 0x1c9bc,
+ 0x1c9c6, 0x1c9cc, 0x1c9d8, 0x1c9ee, 0x1c9f2, 0x1c9f4, 0x1ca38, 0x1ca70, 0x1ca7e, 0x1cae0, 0x1cafc, 0x1cb02,
+ 0x1cb04, 0x1cb08, 0x1cb10, 0x1cb20, 0x1cb3c, 0x1cb40, 0x1cb78, 0x1cb86, 0x1cb8c, 0x1cb98, 0x1cbb0, 0x1cbbe,
+ 0x1cbce, 0x1cbdc, 0x1cbe2, 0x1cbe4, 0x1cbe8, 0x1cbf6, 0x1cc16, 0x1cc26, 0x1cc2c, 0x1cc3a, 0x1cc46, 0x1cc58,
+ 0x1cc72, 0x1cc74, 0x1cc86, 0x1ccb0, 0x1ccbe, 0x1ccce, 0x1cce2, 0x1cce4, 0x1cce8, 0x1cd06, 0x1cd0c, 0x1cd18,
+ 0x1cd30, 0x1cd3e, 0x1cd60, 0x1cd7c, 0x1cd9c, 0x1cdc2, 0x1cdc4, 0x1cdc8, 0x1cdd0, 0x1cdde, 0x1cde6, 0x1cdfa,
+ 0x1ce22, 0x1ce28, 0x1ce42, 0x1ce50, 0x1ce5e, 0x1ce66, 0x1ce7a, 0x1ce82, 0x1ce84, 0x1ce88, 0x1ce90, 0x1ce9e,
+ 0x1cea0, 0x1cebc, 0x1cecc, 0x1cef2, 0x1cef4, 0x1cf2e, 0x1cf32, 0x1cf34, 0x1cf4e, 0x1cf5c, 0x1cf62, 0x1cf64,
+ 0x1cf68, 0x1cf96, 0x1cfa6, 0x1cfac, 0x1cfca, 0x1cfd2, 0x1cfd4, 0x1d02e, 0x1d032, 0x1d034, 0x1d04e, 0x1d05c,
+ 0x1d062, 0x1d064, 0x1d068, 0x1d076, 0x1d08e, 0x1d09c, 0x1d0b8, 0x1d0c2, 0x1d0c4, 0x1d0c8, 0x1d0d0, 0x1d0de,
+ 0x1d0e6, 0x1d0ec, 0x1d0fa, 0x1d11c, 0x1d138, 0x1d170, 0x1d17e, 0x1d182, 0x1d184, 0x1d188, 0x1d190, 0x1d19e,
+ 0x1d1a0, 0x1d1bc, 0x1d1c6, 0x1d1cc, 0x1d1d8, 0x1d1ee, 0x1d1f2, 0x1d1f4, 0x1d21c, 0x1d238, 0x1d270, 0x1d27e,
+ 0x1d2e0, 0x1d2fc, 0x1d302, 0x1d304, 0x1d308, 0x1d310, 0x1d31e, 0x1d320, 0x1d33c, 0x1d340, 0x1d378, 0x1d386,
+ 0x1d38c, 0x1d398, 0x1d3b0, 0x1d3be, 0x1d3ce, 0x1d3dc, 0x1d3e2, 0x1d3e4, 0x1d3e8, 0x1d3f6, 0x1d470, 0x1d47e,
+ 0x1d4e0, 0x1d4fc, 0x1d5c0, 0x1d5f8, 0x1d604, 0x1d608, 0x1d610, 0x1d620, 0x1d640, 0x1d678, 0x1d6f0, 0x1d706,
+ 0x1d70c, 0x1d718, 0x1d730, 0x1d73e, 0x1d760, 0x1d77c, 0x1d78e, 0x1d79c, 0x1d7b8, 0x1d7c2, 0x1d7c4, 0x1d7c8,
+ 0x1d7d0, 0x1d7de, 0x1d7e6, 0x1d7ec, 0x1d826, 0x1d82c, 0x1d83a, 0x1d846, 0x1d84c, 0x1d858, 0x1d872, 0x1d874,
+ 0x1d886, 0x1d88c, 0x1d898, 0x1d8b0, 0x1d8be, 0x1d8ce, 0x1d8e2, 0x1d8e4, 0x1d8e8, 0x1d8f6, 0x1d90c, 0x1d918,
+ 0x1d930, 0x1d93e, 0x1d960, 0x1d97c, 0x1d99c, 0x1d9c2, 0x1d9c4, 0x1d9c8, 0x1d9d0, 0x1d9e6, 0x1d9fa, 0x1da0c,
+ 0x1da18, 0x1da30, 0x1da3e, 0x1da60, 0x1da7c, 0x1dac0, 0x1daf8, 0x1db38, 0x1db82, 0x1db84, 0x1db88, 0x1db90,
+ 0x1db9e, 0x1dba0, 0x1dbcc, 0x1dbf2, 0x1dbf4, 0x1dc22, 0x1dc42, 0x1dc44, 0x1dc48, 0x1dc50, 0x1dc5e, 0x1dc66,
+ 0x1dc7a, 0x1dc82, 0x1dc84, 0x1dc88, 0x1dc90, 0x1dc9e, 0x1dca0, 0x1dcbc, 0x1dccc, 0x1dcf2, 0x1dcf4, 0x1dd04,
+ 0x1dd08, 0x1dd10, 0x1dd1e, 0x1dd20, 0x1dd3c, 0x1dd40, 0x1dd78, 0x1dd86, 0x1dd98, 0x1ddce, 0x1dde2, 0x1dde4,
+ 0x1dde8, 0x1de2e, 0x1de32, 0x1de34, 0x1de4e, 0x1de5c, 0x1de62, 0x1de64, 0x1de68, 0x1de8e, 0x1de9c, 0x1deb8,
+ 0x1dec2, 0x1dec4, 0x1dec8, 0x1ded0, 0x1dee6, 0x1defa, 0x1df16, 0x1df26, 0x1df2c, 0x1df46, 0x1df4c, 0x1df58,
+ 0x1df72, 0x1df74, 0x1df8a, 0x1df92, 0x1df94, 0x1dfa2, 0x1dfa4, 0x1dfa8, 0x1e08a, 0x1e092, 0x1e094, 0x1e0a2,
+ 0x1e0a4, 0x1e0a8, 0x1e0b6, 0x1e0da, 0x1e10a, 0x1e112, 0x1e114, 0x1e122, 0x1e124, 0x1e128, 0x1e136, 0x1e142,
+ 0x1e144, 0x1e148, 0x1e150, 0x1e166, 0x1e16c, 0x1e17a, 0x1e19a, 0x1e1b2, 0x1e1b4, 0x1e20a, 0x1e212, 0x1e214,
+ 0x1e222, 0x1e224, 0x1e228, 0x1e236, 0x1e242, 0x1e248, 0x1e250, 0x1e25e, 0x1e266, 0x1e26c, 0x1e27a, 0x1e282,
+ 0x1e284, 0x1e288, 0x1e290, 0x1e2a0, 0x1e2bc, 0x1e2c6, 0x1e2cc, 0x1e2d8, 0x1e2ee, 0x1e2f2, 0x1e2f4, 0x1e31a,
+ 0x1e332, 0x1e334, 0x1e35c, 0x1e362, 0x1e364, 0x1e368, 0x1e3ba, 0x1e40a, 0x1e412, 0x1e414, 0x1e422, 0x1e428,
+ 0x1e436, 0x1e442, 0x1e448, 0x1e450, 0x1e45e, 0x1e466, 0x1e46c, 0x1e47a, 0x1e482, 0x1e484, 0x1e490, 0x1e49e,
+ 0x1e4a0, 0x1e4bc, 0x1e4c6, 0x1e4cc, 0x1e4d8, 0x1e4ee, 0x1e4f2, 0x1e4f4, 0x1e502, 0x1e504, 0x1e508, 0x1e510,
+ 0x1e51e, 0x1e520, 0x1e53c, 0x1e540, 0x1e578, 0x1e586, 0x1e58c, 0x1e598, 0x1e5b0, 0x1e5be, 0x1e5ce, 0x1e5dc,
+ 0x1e5e2, 0x1e5e4, 0x1e5e8, 0x1e5f6, 0x1e61a, 0x1e62e, 0x1e632, 0x1e634, 0x1e64e, 0x1e65c, 0x1e662, 0x1e668,
+ 0x1e68e, 0x1e69c, 0x1e6b8, 0x1e6c2, 0x1e6c4, 0x1e6c8, 0x1e6d0, 0x1e6e6, 0x1e6fa, 0x1e716, 0x1e726, 0x1e72c,
+ 0x1e73a, 0x1e746, 0x1e74c, 0x1e758, 0x1e772, 0x1e774, 0x1e792, 0x1e794, 0x1e7a2, 0x1e7a4, 0x1e7a8, 0x1e7b6,
+ 0x1e812, 0x1e814, 0x1e822, 0x1e824, 0x1e828, 0x1e836, 0x1e842, 0x1e844, 0x1e848, 0x1e850, 0x1e85e, 0x1e866,
+ 0x1e86c, 0x1e87a, 0x1e882, 0x1e884, 0x1e888, 0x1e890, 0x1e89e, 0x1e8a0, 0x1e8bc, 0x1e8c6, 0x1e8cc, 0x1e8d8,
+ 0x1e8ee, 0x1e8f2, 0x1e8f4, 0x1e902, 0x1e904, 0x1e908, 0x1e910, 0x1e920, 0x1e93c, 0x1e940, 0x1e978, 0x1e986,
+ 0x1e98c, 0x1e998, 0x1e9b0, 0x1e9be, 0x1e9ce, 0x1e9dc, 0x1e9e2, 0x1e9e4, 0x1e9e8, 0x1e9f6, 0x1ea04, 0x1ea08,
+ 0x1ea10, 0x1ea20, 0x1ea40, 0x1ea78, 0x1eaf0, 0x1eb06, 0x1eb0c, 0x1eb18, 0x1eb30, 0x1eb3e, 0x1eb60, 0x1eb7c,
+ 0x1eb8e, 0x1eb9c, 0x1ebb8, 0x1ebc2, 0x1ebc4, 0x1ebc8, 0x1ebd0, 0x1ebde, 0x1ebe6, 0x1ebec, 0x1ec1a, 0x1ec2e,
+ 0x1ec32, 0x1ec34, 0x1ec4e, 0x1ec5c, 0x1ec62, 0x1ec64, 0x1ec68, 0x1ec8e, 0x1ec9c, 0x1ecb8, 0x1ecc2, 0x1ecc4,
+ 0x1ecc8, 0x1ecd0, 0x1ece6, 0x1ecfa, 0x1ed0e, 0x1ed1c, 0x1ed38, 0x1ed70, 0x1ed7e, 0x1ed82, 0x1ed84, 0x1ed88,
+ 0x1ed90, 0x1ed9e, 0x1eda0, 0x1edcc, 0x1edf2, 0x1edf4, 0x1ee16, 0x1ee26, 0x1ee2c, 0x1ee3a, 0x1ee46, 0x1ee4c,
+ 0x1ee58, 0x1ee6e, 0x1ee72, 0x1ee74, 0x1ee86, 0x1ee8c, 0x1ee98, 0x1eeb0, 0x1eebe, 0x1eece, 0x1eedc, 0x1eee2,
+ 0x1eee4, 0x1eee8, 0x1ef12, 0x1ef22, 0x1ef24, 0x1ef28, 0x1ef36, 0x1ef42, 0x1ef44, 0x1ef48, 0x1ef50, 0x1ef5e,
+ 0x1ef66, 0x1ef6c, 0x1ef7a, 0x1efae, 0x1efb2, 0x1efb4, 0x1efd6, 0x1f096, 0x1f0a6, 0x1f0ac, 0x1f0ba, 0x1f0ca,
+ 0x1f0d2, 0x1f0d4, 0x1f116, 0x1f126, 0x1f12c, 0x1f13a, 0x1f146, 0x1f14c, 0x1f158, 0x1f16e, 0x1f172, 0x1f174,
+ 0x1f18a, 0x1f192, 0x1f194, 0x1f1a2, 0x1f1a4, 0x1f1a8, 0x1f1da, 0x1f216, 0x1f226, 0x1f22c, 0x1f23a, 0x1f246,
+ 0x1f258, 0x1f26e, 0x1f272, 0x1f274, 0x1f286, 0x1f28c, 0x1f298, 0x1f2b0, 0x1f2be, 0x1f2ce, 0x1f2dc, 0x1f2e2,
+ 0x1f2e4, 0x1f2e8, 0x1f2f6, 0x1f30a, 0x1f312, 0x1f314, 0x1f322, 0x1f328, 0x1f342, 0x1f344, 0x1f348, 0x1f350,
+ 0x1f35e, 0x1f366, 0x1f37a, 0x1f39a, 0x1f3ae, 0x1f3b2, 0x1f3b4, 0x1f416, 0x1f426, 0x1f42c, 0x1f43a, 0x1f446,
+ 0x1f44c, 0x1f458, 0x1f46e, 0x1f472, 0x1f474, 0x1f486, 0x1f48c, 0x1f498, 0x1f4b0, 0x1f4be, 0x1f4ce, 0x1f4dc,
+ 0x1f4e2, 0x1f4e4, 0x1f4e8, 0x1f4f6, 0x1f506, 0x1f50c, 0x1f518, 0x1f530, 0x1f53e, 0x1f560, 0x1f57c, 0x1f58e,
+ 0x1f59c, 0x1f5b8, 0x1f5c2, 0x1f5c4, 0x1f5c8, 0x1f5d0, 0x1f5de, 0x1f5e6, 0x1f5ec, 0x1f5fa, 0x1f60a, 0x1f612,
+ 0x1f614, 0x1f622, 0x1f624, 0x1f628, 0x1f636, 0x1f642, 0x1f644, 0x1f648, 0x1f650, 0x1f65e, 0x1f666, 0x1f67a,
+ 0x1f682, 0x1f684, 0x1f688, 0x1f690, 0x1f69e, 0x1f6a0, 0x1f6bc, 0x1f6cc, 0x1f6f2, 0x1f6f4, 0x1f71a, 0x1f72e,
+ 0x1f732, 0x1f734, 0x1f74e, 0x1f75c, 0x1f762, 0x1f764, 0x1f768, 0x1f776, 0x1f796, 0x1f7a6, 0x1f7ac, 0x1f7ba,
+ 0x1f7d2, 0x1f7d4, 0x1f89a, 0x1f8ae, 0x1f8b2, 0x1f8b4, 0x1f8d6, 0x1f8ea, 0x1f91a, 0x1f92e, 0x1f932, 0x1f934,
+ 0x1f94e, 0x1f95c, 0x1f962, 0x1f964, 0x1f968, 0x1f976, 0x1f996, 0x1f9a6, 0x1f9ac, 0x1f9ba, 0x1f9ca, 0x1f9d2,
+ 0x1f9d4, 0x1fa1a, 0x1fa2e, 0x1fa32, 0x1fa34, 0x1fa4e, 0x1fa5c, 0x1fa62, 0x1fa64, 0x1fa68, 0x1fa76, 0x1fa8e,
+ 0x1fa9c, 0x1fab8, 0x1fac2, 0x1fac4, 0x1fac8, 0x1fad0, 0x1fade, 0x1fae6, 0x1faec, 0x1fb16, 0x1fb26, 0x1fb2c,
+ 0x1fb3a, 0x1fb46, 0x1fb4c, 0x1fb58, 0x1fb6e, 0x1fb72, 0x1fb74, 0x1fb8a, 0x1fb92, 0x1fb94, 0x1fba2, 0x1fba4,
+ 0x1fba8, 0x1fbb6, 0x1fbda]);
- /**
- * This table contains to codewords for all symbols.
- */
- private static /*final int[]*/ CODEWORD_TABLE = Int32Array.from([
- 2627, 1819, 2622, 2621, 1813, 1812, 2729, 2724, 2723, 2779, 2774, 2773, 902, 896, 908, 868, 865, 861, 859, 2511,
- 873, 871, 1780, 835, 2493, 825, 2491, 842, 837, 844, 1764, 1762, 811, 810, 809, 2483, 807, 2482, 806, 2480, 815,
- 814, 813, 812, 2484, 817, 816, 1745, 1744, 1742, 1746, 2655, 2637, 2635, 2626, 2625, 2623, 2628, 1820, 2752,
- 2739, 2737, 2728, 2727, 2725, 2730, 2785, 2783, 2778, 2777, 2775, 2780, 787, 781, 747, 739, 736, 2413, 754, 752,
- 1719, 692, 689, 681, 2371, 678, 2369, 700, 697, 694, 703, 1688, 1686, 642, 638, 2343, 631, 2341, 627, 2338, 651,
- 646, 643, 2345, 654, 652, 1652, 1650, 1647, 1654, 601, 599, 2322, 596, 2321, 594, 2319, 2317, 611, 610, 608, 606,
- 2324, 603, 2323, 615, 614, 612, 1617, 1616, 1614, 1612, 616, 1619, 1618, 2575, 2538, 2536, 905, 901, 898, 909,
- 2509, 2507, 2504, 870, 867, 864, 860, 2512, 875, 872, 1781, 2490, 2489, 2487, 2485, 1748, 836, 834, 832, 830,
- 2494, 827, 2492, 843, 841, 839, 845, 1765, 1763, 2701, 2676, 2674, 2653, 2648, 2656, 2634, 2633, 2631, 2629,
- 1821, 2638, 2636, 2770, 2763, 2761, 2750, 2745, 2753, 2736, 2735, 2733, 2731, 1848, 2740, 2738, 2786, 2784, 591,
- 588, 576, 569, 566, 2296, 1590, 537, 534, 526, 2276, 522, 2274, 545, 542, 539, 548, 1572, 1570, 481, 2245, 466,
- 2242, 462, 2239, 492, 485, 482, 2249, 496, 494, 1534, 1531, 1528, 1538, 413, 2196, 406, 2191, 2188, 425, 419,
- 2202, 415, 2199, 432, 430, 427, 1472, 1467, 1464, 433, 1476, 1474, 368, 367, 2160, 365, 2159, 362, 2157, 2155,
- 2152, 378, 377, 375, 2166, 372, 2165, 369, 2162, 383, 381, 379, 2168, 1419, 1418, 1416, 1414, 385, 1411, 384,
- 1423, 1422, 1420, 1424, 2461, 802, 2441, 2439, 790, 786, 783, 794, 2409, 2406, 2403, 750, 742, 738, 2414, 756,
- 753, 1720, 2367, 2365, 2362, 2359, 1663, 693, 691, 684, 2373, 680, 2370, 702, 699, 696, 704, 1690, 1687, 2337,
- 2336, 2334, 2332, 1624, 2329, 1622, 640, 637, 2344, 634, 2342, 630, 2340, 650, 648, 645, 2346, 655, 653, 1653,
- 1651, 1649, 1655, 2612, 2597, 2595, 2571, 2568, 2565, 2576, 2534, 2529, 2526, 1787, 2540, 2537, 907, 904, 900,
- 910, 2503, 2502, 2500, 2498, 1768, 2495, 1767, 2510, 2508, 2506, 869, 866, 863, 2513, 876, 874, 1782, 2720, 2713,
- 2711, 2697, 2694, 2691, 2702, 2672, 2670, 2664, 1828, 2678, 2675, 2647, 2646, 2644, 2642, 1823, 2639, 1822, 2654,
- 2652, 2650, 2657, 2771, 1855, 2765, 2762, 1850, 1849, 2751, 2749, 2747, 2754, 353, 2148, 344, 342, 336, 2142,
- 332, 2140, 345, 1375, 1373, 306, 2130, 299, 2128, 295, 2125, 319, 314, 311, 2132, 1354, 1352, 1349, 1356, 262,
- 257, 2101, 253, 2096, 2093, 274, 273, 267, 2107, 263, 2104, 280, 278, 275, 1316, 1311, 1308, 1320, 1318, 2052,
- 202, 2050, 2044, 2040, 219, 2063, 212, 2060, 208, 2055, 224, 221, 2066, 1260, 1258, 1252, 231, 1248, 229, 1266,
- 1264, 1261, 1268, 155, 1998, 153, 1996, 1994, 1991, 1988, 165, 164, 2007, 162, 2006, 159, 2003, 2000, 172, 171,
- 169, 2012, 166, 2010, 1186, 1184, 1182, 1179, 175, 1176, 173, 1192, 1191, 1189, 1187, 176, 1194, 1193, 2313,
- 2307, 2305, 592, 589, 2294, 2292, 2289, 578, 572, 568, 2297, 580, 1591, 2272, 2267, 2264, 1547, 538, 536, 529,
- 2278, 525, 2275, 547, 544, 541, 1574, 1571, 2237, 2235, 2229, 1493, 2225, 1489, 478, 2247, 470, 2244, 465, 2241,
- 493, 488, 484, 2250, 498, 495, 1536, 1533, 1530, 1539, 2187, 2186, 2184, 2182, 1432, 2179, 1430, 2176, 1427, 414,
- 412, 2197, 409, 2195, 405, 2193, 2190, 426, 424, 421, 2203, 418, 2201, 431, 429, 1473, 1471, 1469, 1466, 434,
- 1477, 1475, 2478, 2472, 2470, 2459, 2457, 2454, 2462, 803, 2437, 2432, 2429, 1726, 2443, 2440, 792, 789, 785,
- 2401, 2399, 2393, 1702, 2389, 1699, 2411, 2408, 2405, 745, 741, 2415, 758, 755, 1721, 2358, 2357, 2355, 2353,
- 1661, 2350, 1660, 2347, 1657, 2368, 2366, 2364, 2361, 1666, 690, 687, 2374, 683, 2372, 701, 698, 705, 1691, 1689,
- 2619, 2617, 2610, 2608, 2605, 2613, 2593, 2588, 2585, 1803, 2599, 2596, 2563, 2561, 2555, 1797, 2551, 1795, 2573,
- 2570, 2567, 2577, 2525, 2524, 2522, 2520, 1786, 2517, 1785, 2514, 1783, 2535, 2533, 2531, 2528, 1788, 2541, 2539,
- 906, 903, 911, 2721, 1844, 2715, 2712, 1838, 1836, 2699, 2696, 2693, 2703, 1827, 1826, 1824, 2673, 2671, 2669,
- 2666, 1829, 2679, 2677, 1858, 1857, 2772, 1854, 1853, 1851, 1856, 2766, 2764, 143, 1987, 139, 1986, 135, 133,
- 131, 1984, 128, 1983, 125, 1981, 138, 137, 136, 1985, 1133, 1132, 1130, 112, 110, 1974, 107, 1973, 104, 1971,
- 1969, 122, 121, 119, 117, 1977, 114, 1976, 124, 1115, 1114, 1112, 1110, 1117, 1116, 84, 83, 1953, 81, 1952, 78,
- 1950, 1948, 1945, 94, 93, 91, 1959, 88, 1958, 85, 1955, 99, 97, 95, 1961, 1086, 1085, 1083, 1081, 1078, 100,
- 1090, 1089, 1087, 1091, 49, 47, 1917, 44, 1915, 1913, 1910, 1907, 59, 1926, 56, 1925, 53, 1922, 1919, 66, 64,
- 1931, 61, 1929, 1042, 1040, 1038, 71, 1035, 70, 1032, 68, 1048, 1047, 1045, 1043, 1050, 1049, 12, 10, 1869, 1867,
- 1864, 1861, 21, 1880, 19, 1877, 1874, 1871, 28, 1888, 25, 1886, 22, 1883, 982, 980, 977, 974, 32, 30, 991, 989,
- 987, 984, 34, 995, 994, 992, 2151, 2150, 2147, 2146, 2144, 356, 355, 354, 2149, 2139, 2138, 2136, 2134, 1359,
- 343, 341, 338, 2143, 335, 2141, 348, 347, 346, 1376, 1374, 2124, 2123, 2121, 2119, 1326, 2116, 1324, 310, 308,
- 305, 2131, 302, 2129, 298, 2127, 320, 318, 316, 313, 2133, 322, 321, 1355, 1353, 1351, 1357, 2092, 2091, 2089,
- 2087, 1276, 2084, 1274, 2081, 1271, 259, 2102, 256, 2100, 252, 2098, 2095, 272, 269, 2108, 266, 2106, 281, 279,
- 277, 1317, 1315, 1313, 1310, 282, 1321, 1319, 2039, 2037, 2035, 2032, 1203, 2029, 1200, 1197, 207, 2053, 205,
- 2051, 201, 2049, 2046, 2043, 220, 218, 2064, 215, 2062, 211, 2059, 228, 226, 223, 2069, 1259, 1257, 1254, 232,
- 1251, 230, 1267, 1265, 1263, 2316, 2315, 2312, 2311, 2309, 2314, 2304, 2303, 2301, 2299, 1593, 2308, 2306, 590,
- 2288, 2287, 2285, 2283, 1578, 2280, 1577, 2295, 2293, 2291, 579, 577, 574, 571, 2298, 582, 581, 1592, 2263, 2262,
- 2260, 2258, 1545, 2255, 1544, 2252, 1541, 2273, 2271, 2269, 2266, 1550, 535, 532, 2279, 528, 2277, 546, 543, 549,
- 1575, 1573, 2224, 2222, 2220, 1486, 2217, 1485, 2214, 1482, 1479, 2238, 2236, 2234, 2231, 1496, 2228, 1492, 480,
- 477, 2248, 473, 2246, 469, 2243, 490, 487, 2251, 497, 1537, 1535, 1532, 2477, 2476, 2474, 2479, 2469, 2468, 2466,
- 2464, 1730, 2473, 2471, 2453, 2452, 2450, 2448, 1729, 2445, 1728, 2460, 2458, 2456, 2463, 805, 804, 2428, 2427,
- 2425, 2423, 1725, 2420, 1724, 2417, 1722, 2438, 2436, 2434, 2431, 1727, 2444, 2442, 793, 791, 788, 795, 2388,
- 2386, 2384, 1697, 2381, 1696, 2378, 1694, 1692, 2402, 2400, 2398, 2395, 1703, 2392, 1701, 2412, 2410, 2407, 751,
- 748, 744, 2416, 759, 757, 1807, 2620, 2618, 1806, 1805, 2611, 2609, 2607, 2614, 1802, 1801, 1799, 2594, 2592,
- 2590, 2587, 1804, 2600, 2598, 1794, 1793, 1791, 1789, 2564, 2562, 2560, 2557, 1798, 2554, 1796, 2574, 2572, 2569,
- 2578, 1847, 1846, 2722, 1843, 1842, 1840, 1845, 2716, 2714, 1835, 1834, 1832, 1830, 1839, 1837, 2700, 2698, 2695,
- 2704, 1817, 1811, 1810, 897, 862, 1777, 829, 826, 838, 1760, 1758, 808, 2481, 1741, 1740, 1738, 1743, 2624, 1818,
- 2726, 2776, 782, 740, 737, 1715, 686, 679, 695, 1682, 1680, 639, 628, 2339, 647, 644, 1645, 1643, 1640, 1648,
- 602, 600, 597, 595, 2320, 593, 2318, 609, 607, 604, 1611, 1610, 1608, 1606, 613, 1615, 1613, 2328, 926, 924, 892,
- 886, 899, 857, 850, 2505, 1778, 824, 823, 821, 819, 2488, 818, 2486, 833, 831, 828, 840, 1761, 1759, 2649, 2632,
- 2630, 2746, 2734, 2732, 2782, 2781, 570, 567, 1587, 531, 527, 523, 540, 1566, 1564, 476, 467, 463, 2240, 486,
- 483, 1524, 1521, 1518, 1529, 411, 403, 2192, 399, 2189, 423, 416, 1462, 1457, 1454, 428, 1468, 1465, 2210, 366,
- 363, 2158, 360, 2156, 357, 2153, 376, 373, 370, 2163, 1410, 1409, 1407, 1405, 382, 1402, 380, 1417, 1415, 1412,
- 1421, 2175, 2174, 777, 774, 771, 784, 732, 725, 722, 2404, 743, 1716, 676, 674, 668, 2363, 665, 2360, 685, 1684,
- 1681, 626, 624, 622, 2335, 620, 2333, 617, 2330, 641, 635, 649, 1646, 1644, 1642, 2566, 928, 925, 2530, 2527,
- 894, 891, 888, 2501, 2499, 2496, 858, 856, 854, 851, 1779, 2692, 2668, 2665, 2645, 2643, 2640, 2651, 2768, 2759,
- 2757, 2744, 2743, 2741, 2748, 352, 1382, 340, 337, 333, 1371, 1369, 307, 300, 296, 2126, 315, 312, 1347, 1342,
- 1350, 261, 258, 250, 2097, 246, 2094, 271, 268, 264, 1306, 1301, 1298, 276, 1312, 1309, 2115, 203, 2048, 195,
- 2045, 191, 2041, 213, 209, 2056, 1246, 1244, 1238, 225, 1234, 222, 1256, 1253, 1249, 1262, 2080, 2079, 154, 1997,
- 150, 1995, 147, 1992, 1989, 163, 160, 2004, 156, 2001, 1175, 1174, 1172, 1170, 1167, 170, 1164, 167, 1185, 1183,
- 1180, 1177, 174, 1190, 1188, 2025, 2024, 2022, 587, 586, 564, 559, 556, 2290, 573, 1588, 520, 518, 512, 2268,
- 508, 2265, 530, 1568, 1565, 461, 457, 2233, 450, 2230, 446, 2226, 479, 471, 489, 1526, 1523, 1520, 397, 395,
- 2185, 392, 2183, 389, 2180, 2177, 410, 2194, 402, 422, 1463, 1461, 1459, 1456, 1470, 2455, 799, 2433, 2430, 779,
- 776, 773, 2397, 2394, 2390, 734, 728, 724, 746, 1717, 2356, 2354, 2351, 2348, 1658, 677, 675, 673, 670, 667, 688,
- 1685, 1683, 2606, 2589, 2586, 2559, 2556, 2552, 927, 2523, 2521, 2518, 2515, 1784, 2532, 895, 893, 890, 2718,
- 2709, 2707, 2689, 2687, 2684, 2663, 2662, 2660, 2658, 1825, 2667, 2769, 1852, 2760, 2758, 142, 141, 1139, 1138,
- 134, 132, 129, 126, 1982, 1129, 1128, 1126, 1131, 113, 111, 108, 105, 1972, 101, 1970, 120, 118, 115, 1109, 1108,
- 1106, 1104, 123, 1113, 1111, 82, 79, 1951, 75, 1949, 72, 1946, 92, 89, 86, 1956, 1077, 1076, 1074, 1072, 98,
- 1069, 96, 1084, 1082, 1079, 1088, 1968, 1967, 48, 45, 1916, 42, 1914, 39, 1911, 1908, 60, 57, 54, 1923, 50, 1920,
- 1031, 1030, 1028, 1026, 67, 1023, 65, 1020, 62, 1041, 1039, 1036, 1033, 69, 1046, 1044, 1944, 1943, 1941, 11, 9,
- 1868, 7, 1865, 1862, 1859, 20, 1878, 16, 1875, 13, 1872, 970, 968, 966, 963, 29, 960, 26, 23, 983, 981, 978, 975,
- 33, 971, 31, 990, 988, 985, 1906, 1904, 1902, 993, 351, 2145, 1383, 331, 330, 328, 326, 2137, 323, 2135, 339,
- 1372, 1370, 294, 293, 291, 289, 2122, 286, 2120, 283, 2117, 309, 303, 317, 1348, 1346, 1344, 245, 244, 242, 2090,
- 239, 2088, 236, 2085, 2082, 260, 2099, 249, 270, 1307, 1305, 1303, 1300, 1314, 189, 2038, 186, 2036, 183, 2033,
- 2030, 2026, 206, 198, 2047, 194, 216, 1247, 1245, 1243, 1240, 227, 1237, 1255, 2310, 2302, 2300, 2286, 2284,
- 2281, 565, 563, 561, 558, 575, 1589, 2261, 2259, 2256, 2253, 1542, 521, 519, 517, 514, 2270, 511, 533, 1569,
- 1567, 2223, 2221, 2218, 2215, 1483, 2211, 1480, 459, 456, 453, 2232, 449, 474, 491, 1527, 1525, 1522, 2475, 2467,
- 2465, 2451, 2449, 2446, 801, 800, 2426, 2424, 2421, 2418, 1723, 2435, 780, 778, 775, 2387, 2385, 2382, 2379,
- 1695, 2375, 1693, 2396, 735, 733, 730, 727, 749, 1718, 2616, 2615, 2604, 2603, 2601, 2584, 2583, 2581, 2579,
- 1800, 2591, 2550, 2549, 2547, 2545, 1792, 2542, 1790, 2558, 929, 2719, 1841, 2710, 2708, 1833, 1831, 2690, 2688,
- 2686, 1815, 1809, 1808, 1774, 1756, 1754, 1737, 1736, 1734, 1739, 1816, 1711, 1676, 1674, 633, 629, 1638, 1636,
- 1633, 1641, 598, 1605, 1604, 1602, 1600, 605, 1609, 1607, 2327, 887, 853, 1775, 822, 820, 1757, 1755, 1584, 524,
- 1560, 1558, 468, 464, 1514, 1511, 1508, 1519, 408, 404, 400, 1452, 1447, 1444, 417, 1458, 1455, 2208, 364, 361,
- 358, 2154, 1401, 1400, 1398, 1396, 374, 1393, 371, 1408, 1406, 1403, 1413, 2173, 2172, 772, 726, 723, 1712, 672,
- 669, 666, 682, 1678, 1675, 625, 623, 621, 618, 2331, 636, 632, 1639, 1637, 1635, 920, 918, 884, 880, 889, 849,
- 848, 847, 846, 2497, 855, 852, 1776, 2641, 2742, 2787, 1380, 334, 1367, 1365, 301, 297, 1340, 1338, 1335, 1343,
- 255, 251, 247, 1296, 1291, 1288, 265, 1302, 1299, 2113, 204, 196, 192, 2042, 1232, 1230, 1224, 214, 1220, 210,
- 1242, 1239, 1235, 1250, 2077, 2075, 151, 148, 1993, 144, 1990, 1163, 1162, 1160, 1158, 1155, 161, 1152, 157,
- 1173, 1171, 1168, 1165, 168, 1181, 1178, 2021, 2020, 2018, 2023, 585, 560, 557, 1585, 516, 509, 1562, 1559, 458,
- 447, 2227, 472, 1516, 1513, 1510, 398, 396, 393, 390, 2181, 386, 2178, 407, 1453, 1451, 1449, 1446, 420, 1460,
- 2209, 769, 764, 720, 712, 2391, 729, 1713, 664, 663, 661, 659, 2352, 656, 2349, 671, 1679, 1677, 2553, 922, 919,
- 2519, 2516, 885, 883, 881, 2685, 2661, 2659, 2767, 2756, 2755, 140, 1137, 1136, 130, 127, 1125, 1124, 1122, 1127,
- 109, 106, 102, 1103, 1102, 1100, 1098, 116, 1107, 1105, 1980, 80, 76, 73, 1947, 1068, 1067, 1065, 1063, 90, 1060,
- 87, 1075, 1073, 1070, 1080, 1966, 1965, 46, 43, 40, 1912, 36, 1909, 1019, 1018, 1016, 1014, 58, 1011, 55, 1008,
- 51, 1029, 1027, 1024, 1021, 63, 1037, 1034, 1940, 1939, 1937, 1942, 8, 1866, 4, 1863, 1, 1860, 956, 954, 952,
- 949, 946, 17, 14, 969, 967, 964, 961, 27, 957, 24, 979, 976, 972, 1901, 1900, 1898, 1896, 986, 1905, 1903, 350,
- 349, 1381, 329, 327, 324, 1368, 1366, 292, 290, 287, 284, 2118, 304, 1341, 1339, 1337, 1345, 243, 240, 237, 2086,
- 233, 2083, 254, 1297, 1295, 1293, 1290, 1304, 2114, 190, 187, 184, 2034, 180, 2031, 177, 2027, 199, 1233, 1231,
- 1229, 1226, 217, 1223, 1241, 2078, 2076, 584, 555, 554, 552, 550, 2282, 562, 1586, 507, 506, 504, 502, 2257, 499,
- 2254, 515, 1563, 1561, 445, 443, 441, 2219, 438, 2216, 435, 2212, 460, 454, 475, 1517, 1515, 1512, 2447, 798,
- 797, 2422, 2419, 770, 768, 766, 2383, 2380, 2376, 721, 719, 717, 714, 731, 1714, 2602, 2582, 2580, 2548, 2546,
- 2543, 923, 921, 2717, 2706, 2705, 2683, 2682, 2680, 1771, 1752, 1750, 1733, 1732, 1731, 1735, 1814, 1707, 1670,
- 1668, 1631, 1629, 1626, 1634, 1599, 1598, 1596, 1594, 1603, 1601, 2326, 1772, 1753, 1751, 1581, 1554, 1552, 1504,
- 1501, 1498, 1509, 1442, 1437, 1434, 401, 1448, 1445, 2206, 1392, 1391, 1389, 1387, 1384, 359, 1399, 1397, 1394,
- 1404, 2171, 2170, 1708, 1672, 1669, 619, 1632, 1630, 1628, 1773, 1378, 1363, 1361, 1333, 1328, 1336, 1286, 1281,
- 1278, 248, 1292, 1289, 2111, 1218, 1216, 1210, 197, 1206, 193, 1228, 1225, 1221, 1236, 2073, 2071, 1151, 1150,
- 1148, 1146, 152, 1143, 149, 1140, 145, 1161, 1159, 1156, 1153, 158, 1169, 1166, 2017, 2016, 2014, 2019, 1582,
- 510, 1556, 1553, 452, 448, 1506, 1500, 394, 391, 387, 1443, 1441, 1439, 1436, 1450, 2207, 765, 716, 713, 1709,
- 662, 660, 657, 1673, 1671, 916, 914, 879, 878, 877, 882, 1135, 1134, 1121, 1120, 1118, 1123, 1097, 1096, 1094,
- 1092, 103, 1101, 1099, 1979, 1059, 1058, 1056, 1054, 77, 1051, 74, 1066, 1064, 1061, 1071, 1964, 1963, 1007,
- 1006, 1004, 1002, 999, 41, 996, 37, 1017, 1015, 1012, 1009, 52, 1025, 1022, 1936, 1935, 1933, 1938, 942, 940,
- 938, 935, 932, 5, 2, 955, 953, 950, 947, 18, 943, 15, 965, 962, 958, 1895, 1894, 1892, 1890, 973, 1899, 1897,
- 1379, 325, 1364, 1362, 288, 285, 1334, 1332, 1330, 241, 238, 234, 1287, 1285, 1283, 1280, 1294, 2112, 188, 185,
- 181, 178, 2028, 1219, 1217, 1215, 1212, 200, 1209, 1227, 2074, 2072, 583, 553, 551, 1583, 505, 503, 500, 513,
- 1557, 1555, 444, 442, 439, 436, 2213, 455, 451, 1507, 1505, 1502, 796, 763, 762, 760, 767, 711, 710, 708, 706,
- 2377, 718, 715, 1710, 2544, 917, 915, 2681, 1627, 1597, 1595, 2325, 1769, 1749, 1747, 1499, 1438, 1435, 2204,
- 1390, 1388, 1385, 1395, 2169, 2167, 1704, 1665, 1662, 1625, 1623, 1620, 1770, 1329, 1282, 1279, 2109, 1214, 1207,
- 1222, 2068, 2065, 1149, 1147, 1144, 1141, 146, 1157, 1154, 2013, 2011, 2008, 2015, 1579, 1549, 1546, 1495, 1487,
- 1433, 1431, 1428, 1425, 388, 1440, 2205, 1705, 658, 1667, 1664, 1119, 1095, 1093, 1978, 1057, 1055, 1052, 1062,
- 1962, 1960, 1005, 1003, 1000, 997, 38, 1013, 1010, 1932, 1930, 1927, 1934, 941, 939, 936, 933, 6, 930, 3, 951,
- 948, 944, 1889, 1887, 1884, 1881, 959, 1893, 1891, 35, 1377, 1360, 1358, 1327, 1325, 1322, 1331, 1277, 1275,
- 1272, 1269, 235, 1284, 2110, 1205, 1204, 1201, 1198, 182, 1195, 179, 1213, 2070, 2067, 1580, 501, 1551, 1548,
- 440, 437, 1497, 1494, 1490, 1503, 761, 709, 707, 1706, 913, 912, 2198, 1386, 2164, 2161, 1621, 1766, 2103, 1208,
- 2058, 2054, 1145, 1142, 2005, 2002, 1999, 2009, 1488, 1429, 1426, 2200, 1698, 1659, 1656, 1975, 1053, 1957, 1954,
- 1001, 998, 1924, 1921, 1918, 1928, 937, 934, 931, 1879, 1876, 1873, 1870, 945, 1885, 1882, 1323, 1273, 1270,
- 2105, 1202, 1199, 1196, 1211, 2061, 2057, 1576, 1543, 1540, 1484, 1481, 1478, 1491, 1700]);
+ /**
+ * This table contains to codewords for all symbols.
+ */
+ private static /* final int[] */ CODEWORD_TABLE = Int32Array.from([
+ 2627, 1819, 2622, 2621, 1813, 1812, 2729, 2724, 2723, 2779, 2774, 2773, 902, 896, 908, 868, 865, 861, 859, 2511,
+ 873, 871, 1780, 835, 2493, 825, 2491, 842, 837, 844, 1764, 1762, 811, 810, 809, 2483, 807, 2482, 806, 2480, 815,
+ 814, 813, 812, 2484, 817, 816, 1745, 1744, 1742, 1746, 2655, 2637, 2635, 2626, 2625, 2623, 2628, 1820, 2752,
+ 2739, 2737, 2728, 2727, 2725, 2730, 2785, 2783, 2778, 2777, 2775, 2780, 787, 781, 747, 739, 736, 2413, 754, 752,
+ 1719, 692, 689, 681, 2371, 678, 2369, 700, 697, 694, 703, 1688, 1686, 642, 638, 2343, 631, 2341, 627, 2338, 651,
+ 646, 643, 2345, 654, 652, 1652, 1650, 1647, 1654, 601, 599, 2322, 596, 2321, 594, 2319, 2317, 611, 610, 608, 606,
+ 2324, 603, 2323, 615, 614, 612, 1617, 1616, 1614, 1612, 616, 1619, 1618, 2575, 2538, 2536, 905, 901, 898, 909,
+ 2509, 2507, 2504, 870, 867, 864, 860, 2512, 875, 872, 1781, 2490, 2489, 2487, 2485, 1748, 836, 834, 832, 830,
+ 2494, 827, 2492, 843, 841, 839, 845, 1765, 1763, 2701, 2676, 2674, 2653, 2648, 2656, 2634, 2633, 2631, 2629,
+ 1821, 2638, 2636, 2770, 2763, 2761, 2750, 2745, 2753, 2736, 2735, 2733, 2731, 1848, 2740, 2738, 2786, 2784, 591,
+ 588, 576, 569, 566, 2296, 1590, 537, 534, 526, 2276, 522, 2274, 545, 542, 539, 548, 1572, 1570, 481, 2245, 466,
+ 2242, 462, 2239, 492, 485, 482, 2249, 496, 494, 1534, 1531, 1528, 1538, 413, 2196, 406, 2191, 2188, 425, 419,
+ 2202, 415, 2199, 432, 430, 427, 1472, 1467, 1464, 433, 1476, 1474, 368, 367, 2160, 365, 2159, 362, 2157, 2155,
+ 2152, 378, 377, 375, 2166, 372, 2165, 369, 2162, 383, 381, 379, 2168, 1419, 1418, 1416, 1414, 385, 1411, 384,
+ 1423, 1422, 1420, 1424, 2461, 802, 2441, 2439, 790, 786, 783, 794, 2409, 2406, 2403, 750, 742, 738, 2414, 756,
+ 753, 1720, 2367, 2365, 2362, 2359, 1663, 693, 691, 684, 2373, 680, 2370, 702, 699, 696, 704, 1690, 1687, 2337,
+ 2336, 2334, 2332, 1624, 2329, 1622, 640, 637, 2344, 634, 2342, 630, 2340, 650, 648, 645, 2346, 655, 653, 1653,
+ 1651, 1649, 1655, 2612, 2597, 2595, 2571, 2568, 2565, 2576, 2534, 2529, 2526, 1787, 2540, 2537, 907, 904, 900,
+ 910, 2503, 2502, 2500, 2498, 1768, 2495, 1767, 2510, 2508, 2506, 869, 866, 863, 2513, 876, 874, 1782, 2720, 2713,
+ 2711, 2697, 2694, 2691, 2702, 2672, 2670, 2664, 1828, 2678, 2675, 2647, 2646, 2644, 2642, 1823, 2639, 1822, 2654,
+ 2652, 2650, 2657, 2771, 1855, 2765, 2762, 1850, 1849, 2751, 2749, 2747, 2754, 353, 2148, 344, 342, 336, 2142,
+ 332, 2140, 345, 1375, 1373, 306, 2130, 299, 2128, 295, 2125, 319, 314, 311, 2132, 1354, 1352, 1349, 1356, 262,
+ 257, 2101, 253, 2096, 2093, 274, 273, 267, 2107, 263, 2104, 280, 278, 275, 1316, 1311, 1308, 1320, 1318, 2052,
+ 202, 2050, 2044, 2040, 219, 2063, 212, 2060, 208, 2055, 224, 221, 2066, 1260, 1258, 1252, 231, 1248, 229, 1266,
+ 1264, 1261, 1268, 155, 1998, 153, 1996, 1994, 1991, 1988, 165, 164, 2007, 162, 2006, 159, 2003, 2000, 172, 171,
+ 169, 2012, 166, 2010, 1186, 1184, 1182, 1179, 175, 1176, 173, 1192, 1191, 1189, 1187, 176, 1194, 1193, 2313,
+ 2307, 2305, 592, 589, 2294, 2292, 2289, 578, 572, 568, 2297, 580, 1591, 2272, 2267, 2264, 1547, 538, 536, 529,
+ 2278, 525, 2275, 547, 544, 541, 1574, 1571, 2237, 2235, 2229, 1493, 2225, 1489, 478, 2247, 470, 2244, 465, 2241,
+ 493, 488, 484, 2250, 498, 495, 1536, 1533, 1530, 1539, 2187, 2186, 2184, 2182, 1432, 2179, 1430, 2176, 1427, 414,
+ 412, 2197, 409, 2195, 405, 2193, 2190, 426, 424, 421, 2203, 418, 2201, 431, 429, 1473, 1471, 1469, 1466, 434,
+ 1477, 1475, 2478, 2472, 2470, 2459, 2457, 2454, 2462, 803, 2437, 2432, 2429, 1726, 2443, 2440, 792, 789, 785,
+ 2401, 2399, 2393, 1702, 2389, 1699, 2411, 2408, 2405, 745, 741, 2415, 758, 755, 1721, 2358, 2357, 2355, 2353,
+ 1661, 2350, 1660, 2347, 1657, 2368, 2366, 2364, 2361, 1666, 690, 687, 2374, 683, 2372, 701, 698, 705, 1691, 1689,
+ 2619, 2617, 2610, 2608, 2605, 2613, 2593, 2588, 2585, 1803, 2599, 2596, 2563, 2561, 2555, 1797, 2551, 1795, 2573,
+ 2570, 2567, 2577, 2525, 2524, 2522, 2520, 1786, 2517, 1785, 2514, 1783, 2535, 2533, 2531, 2528, 1788, 2541, 2539,
+ 906, 903, 911, 2721, 1844, 2715, 2712, 1838, 1836, 2699, 2696, 2693, 2703, 1827, 1826, 1824, 2673, 2671, 2669,
+ 2666, 1829, 2679, 2677, 1858, 1857, 2772, 1854, 1853, 1851, 1856, 2766, 2764, 143, 1987, 139, 1986, 135, 133,
+ 131, 1984, 128, 1983, 125, 1981, 138, 137, 136, 1985, 1133, 1132, 1130, 112, 110, 1974, 107, 1973, 104, 1971,
+ 1969, 122, 121, 119, 117, 1977, 114, 1976, 124, 1115, 1114, 1112, 1110, 1117, 1116, 84, 83, 1953, 81, 1952, 78,
+ 1950, 1948, 1945, 94, 93, 91, 1959, 88, 1958, 85, 1955, 99, 97, 95, 1961, 1086, 1085, 1083, 1081, 1078, 100,
+ 1090, 1089, 1087, 1091, 49, 47, 1917, 44, 1915, 1913, 1910, 1907, 59, 1926, 56, 1925, 53, 1922, 1919, 66, 64,
+ 1931, 61, 1929, 1042, 1040, 1038, 71, 1035, 70, 1032, 68, 1048, 1047, 1045, 1043, 1050, 1049, 12, 10, 1869, 1867,
+ 1864, 1861, 21, 1880, 19, 1877, 1874, 1871, 28, 1888, 25, 1886, 22, 1883, 982, 980, 977, 974, 32, 30, 991, 989,
+ 987, 984, 34, 995, 994, 992, 2151, 2150, 2147, 2146, 2144, 356, 355, 354, 2149, 2139, 2138, 2136, 2134, 1359,
+ 343, 341, 338, 2143, 335, 2141, 348, 347, 346, 1376, 1374, 2124, 2123, 2121, 2119, 1326, 2116, 1324, 310, 308,
+ 305, 2131, 302, 2129, 298, 2127, 320, 318, 316, 313, 2133, 322, 321, 1355, 1353, 1351, 1357, 2092, 2091, 2089,
+ 2087, 1276, 2084, 1274, 2081, 1271, 259, 2102, 256, 2100, 252, 2098, 2095, 272, 269, 2108, 266, 2106, 281, 279,
+ 277, 1317, 1315, 1313, 1310, 282, 1321, 1319, 2039, 2037, 2035, 2032, 1203, 2029, 1200, 1197, 207, 2053, 205,
+ 2051, 201, 2049, 2046, 2043, 220, 218, 2064, 215, 2062, 211, 2059, 228, 226, 223, 2069, 1259, 1257, 1254, 232,
+ 1251, 230, 1267, 1265, 1263, 2316, 2315, 2312, 2311, 2309, 2314, 2304, 2303, 2301, 2299, 1593, 2308, 2306, 590,
+ 2288, 2287, 2285, 2283, 1578, 2280, 1577, 2295, 2293, 2291, 579, 577, 574, 571, 2298, 582, 581, 1592, 2263, 2262,
+ 2260, 2258, 1545, 2255, 1544, 2252, 1541, 2273, 2271, 2269, 2266, 1550, 535, 532, 2279, 528, 2277, 546, 543, 549,
+ 1575, 1573, 2224, 2222, 2220, 1486, 2217, 1485, 2214, 1482, 1479, 2238, 2236, 2234, 2231, 1496, 2228, 1492, 480,
+ 477, 2248, 473, 2246, 469, 2243, 490, 487, 2251, 497, 1537, 1535, 1532, 2477, 2476, 2474, 2479, 2469, 2468, 2466,
+ 2464, 1730, 2473, 2471, 2453, 2452, 2450, 2448, 1729, 2445, 1728, 2460, 2458, 2456, 2463, 805, 804, 2428, 2427,
+ 2425, 2423, 1725, 2420, 1724, 2417, 1722, 2438, 2436, 2434, 2431, 1727, 2444, 2442, 793, 791, 788, 795, 2388,
+ 2386, 2384, 1697, 2381, 1696, 2378, 1694, 1692, 2402, 2400, 2398, 2395, 1703, 2392, 1701, 2412, 2410, 2407, 751,
+ 748, 744, 2416, 759, 757, 1807, 2620, 2618, 1806, 1805, 2611, 2609, 2607, 2614, 1802, 1801, 1799, 2594, 2592,
+ 2590, 2587, 1804, 2600, 2598, 1794, 1793, 1791, 1789, 2564, 2562, 2560, 2557, 1798, 2554, 1796, 2574, 2572, 2569,
+ 2578, 1847, 1846, 2722, 1843, 1842, 1840, 1845, 2716, 2714, 1835, 1834, 1832, 1830, 1839, 1837, 2700, 2698, 2695,
+ 2704, 1817, 1811, 1810, 897, 862, 1777, 829, 826, 838, 1760, 1758, 808, 2481, 1741, 1740, 1738, 1743, 2624, 1818,
+ 2726, 2776, 782, 740, 737, 1715, 686, 679, 695, 1682, 1680, 639, 628, 2339, 647, 644, 1645, 1643, 1640, 1648,
+ 602, 600, 597, 595, 2320, 593, 2318, 609, 607, 604, 1611, 1610, 1608, 1606, 613, 1615, 1613, 2328, 926, 924, 892,
+ 886, 899, 857, 850, 2505, 1778, 824, 823, 821, 819, 2488, 818, 2486, 833, 831, 828, 840, 1761, 1759, 2649, 2632,
+ 2630, 2746, 2734, 2732, 2782, 2781, 570, 567, 1587, 531, 527, 523, 540, 1566, 1564, 476, 467, 463, 2240, 486,
+ 483, 1524, 1521, 1518, 1529, 411, 403, 2192, 399, 2189, 423, 416, 1462, 1457, 1454, 428, 1468, 1465, 2210, 366,
+ 363, 2158, 360, 2156, 357, 2153, 376, 373, 370, 2163, 1410, 1409, 1407, 1405, 382, 1402, 380, 1417, 1415, 1412,
+ 1421, 2175, 2174, 777, 774, 771, 784, 732, 725, 722, 2404, 743, 1716, 676, 674, 668, 2363, 665, 2360, 685, 1684,
+ 1681, 626, 624, 622, 2335, 620, 2333, 617, 2330, 641, 635, 649, 1646, 1644, 1642, 2566, 928, 925, 2530, 2527,
+ 894, 891, 888, 2501, 2499, 2496, 858, 856, 854, 851, 1779, 2692, 2668, 2665, 2645, 2643, 2640, 2651, 2768, 2759,
+ 2757, 2744, 2743, 2741, 2748, 352, 1382, 340, 337, 333, 1371, 1369, 307, 300, 296, 2126, 315, 312, 1347, 1342,
+ 1350, 261, 258, 250, 2097, 246, 2094, 271, 268, 264, 1306, 1301, 1298, 276, 1312, 1309, 2115, 203, 2048, 195,
+ 2045, 191, 2041, 213, 209, 2056, 1246, 1244, 1238, 225, 1234, 222, 1256, 1253, 1249, 1262, 2080, 2079, 154, 1997,
+ 150, 1995, 147, 1992, 1989, 163, 160, 2004, 156, 2001, 1175, 1174, 1172, 1170, 1167, 170, 1164, 167, 1185, 1183,
+ 1180, 1177, 174, 1190, 1188, 2025, 2024, 2022, 587, 586, 564, 559, 556, 2290, 573, 1588, 520, 518, 512, 2268,
+ 508, 2265, 530, 1568, 1565, 461, 457, 2233, 450, 2230, 446, 2226, 479, 471, 489, 1526, 1523, 1520, 397, 395,
+ 2185, 392, 2183, 389, 2180, 2177, 410, 2194, 402, 422, 1463, 1461, 1459, 1456, 1470, 2455, 799, 2433, 2430, 779,
+ 776, 773, 2397, 2394, 2390, 734, 728, 724, 746, 1717, 2356, 2354, 2351, 2348, 1658, 677, 675, 673, 670, 667, 688,
+ 1685, 1683, 2606, 2589, 2586, 2559, 2556, 2552, 927, 2523, 2521, 2518, 2515, 1784, 2532, 895, 893, 890, 2718,
+ 2709, 2707, 2689, 2687, 2684, 2663, 2662, 2660, 2658, 1825, 2667, 2769, 1852, 2760, 2758, 142, 141, 1139, 1138,
+ 134, 132, 129, 126, 1982, 1129, 1128, 1126, 1131, 113, 111, 108, 105, 1972, 101, 1970, 120, 118, 115, 1109, 1108,
+ 1106, 1104, 123, 1113, 1111, 82, 79, 1951, 75, 1949, 72, 1946, 92, 89, 86, 1956, 1077, 1076, 1074, 1072, 98,
+ 1069, 96, 1084, 1082, 1079, 1088, 1968, 1967, 48, 45, 1916, 42, 1914, 39, 1911, 1908, 60, 57, 54, 1923, 50, 1920,
+ 1031, 1030, 1028, 1026, 67, 1023, 65, 1020, 62, 1041, 1039, 1036, 1033, 69, 1046, 1044, 1944, 1943, 1941, 11, 9,
+ 1868, 7, 1865, 1862, 1859, 20, 1878, 16, 1875, 13, 1872, 970, 968, 966, 963, 29, 960, 26, 23, 983, 981, 978, 975,
+ 33, 971, 31, 990, 988, 985, 1906, 1904, 1902, 993, 351, 2145, 1383, 331, 330, 328, 326, 2137, 323, 2135, 339,
+ 1372, 1370, 294, 293, 291, 289, 2122, 286, 2120, 283, 2117, 309, 303, 317, 1348, 1346, 1344, 245, 244, 242, 2090,
+ 239, 2088, 236, 2085, 2082, 260, 2099, 249, 270, 1307, 1305, 1303, 1300, 1314, 189, 2038, 186, 2036, 183, 2033,
+ 2030, 2026, 206, 198, 2047, 194, 216, 1247, 1245, 1243, 1240, 227, 1237, 1255, 2310, 2302, 2300, 2286, 2284,
+ 2281, 565, 563, 561, 558, 575, 1589, 2261, 2259, 2256, 2253, 1542, 521, 519, 517, 514, 2270, 511, 533, 1569,
+ 1567, 2223, 2221, 2218, 2215, 1483, 2211, 1480, 459, 456, 453, 2232, 449, 474, 491, 1527, 1525, 1522, 2475, 2467,
+ 2465, 2451, 2449, 2446, 801, 800, 2426, 2424, 2421, 2418, 1723, 2435, 780, 778, 775, 2387, 2385, 2382, 2379,
+ 1695, 2375, 1693, 2396, 735, 733, 730, 727, 749, 1718, 2616, 2615, 2604, 2603, 2601, 2584, 2583, 2581, 2579,
+ 1800, 2591, 2550, 2549, 2547, 2545, 1792, 2542, 1790, 2558, 929, 2719, 1841, 2710, 2708, 1833, 1831, 2690, 2688,
+ 2686, 1815, 1809, 1808, 1774, 1756, 1754, 1737, 1736, 1734, 1739, 1816, 1711, 1676, 1674, 633, 629, 1638, 1636,
+ 1633, 1641, 598, 1605, 1604, 1602, 1600, 605, 1609, 1607, 2327, 887, 853, 1775, 822, 820, 1757, 1755, 1584, 524,
+ 1560, 1558, 468, 464, 1514, 1511, 1508, 1519, 408, 404, 400, 1452, 1447, 1444, 417, 1458, 1455, 2208, 364, 361,
+ 358, 2154, 1401, 1400, 1398, 1396, 374, 1393, 371, 1408, 1406, 1403, 1413, 2173, 2172, 772, 726, 723, 1712, 672,
+ 669, 666, 682, 1678, 1675, 625, 623, 621, 618, 2331, 636, 632, 1639, 1637, 1635, 920, 918, 884, 880, 889, 849,
+ 848, 847, 846, 2497, 855, 852, 1776, 2641, 2742, 2787, 1380, 334, 1367, 1365, 301, 297, 1340, 1338, 1335, 1343,
+ 255, 251, 247, 1296, 1291, 1288, 265, 1302, 1299, 2113, 204, 196, 192, 2042, 1232, 1230, 1224, 214, 1220, 210,
+ 1242, 1239, 1235, 1250, 2077, 2075, 151, 148, 1993, 144, 1990, 1163, 1162, 1160, 1158, 1155, 161, 1152, 157,
+ 1173, 1171, 1168, 1165, 168, 1181, 1178, 2021, 2020, 2018, 2023, 585, 560, 557, 1585, 516, 509, 1562, 1559, 458,
+ 447, 2227, 472, 1516, 1513, 1510, 398, 396, 393, 390, 2181, 386, 2178, 407, 1453, 1451, 1449, 1446, 420, 1460,
+ 2209, 769, 764, 720, 712, 2391, 729, 1713, 664, 663, 661, 659, 2352, 656, 2349, 671, 1679, 1677, 2553, 922, 919,
+ 2519, 2516, 885, 883, 881, 2685, 2661, 2659, 2767, 2756, 2755, 140, 1137, 1136, 130, 127, 1125, 1124, 1122, 1127,
+ 109, 106, 102, 1103, 1102, 1100, 1098, 116, 1107, 1105, 1980, 80, 76, 73, 1947, 1068, 1067, 1065, 1063, 90, 1060,
+ 87, 1075, 1073, 1070, 1080, 1966, 1965, 46, 43, 40, 1912, 36, 1909, 1019, 1018, 1016, 1014, 58, 1011, 55, 1008,
+ 51, 1029, 1027, 1024, 1021, 63, 1037, 1034, 1940, 1939, 1937, 1942, 8, 1866, 4, 1863, 1, 1860, 956, 954, 952,
+ 949, 946, 17, 14, 969, 967, 964, 961, 27, 957, 24, 979, 976, 972, 1901, 1900, 1898, 1896, 986, 1905, 1903, 350,
+ 349, 1381, 329, 327, 324, 1368, 1366, 292, 290, 287, 284, 2118, 304, 1341, 1339, 1337, 1345, 243, 240, 237, 2086,
+ 233, 2083, 254, 1297, 1295, 1293, 1290, 1304, 2114, 190, 187, 184, 2034, 180, 2031, 177, 2027, 199, 1233, 1231,
+ 1229, 1226, 217, 1223, 1241, 2078, 2076, 584, 555, 554, 552, 550, 2282, 562, 1586, 507, 506, 504, 502, 2257, 499,
+ 2254, 515, 1563, 1561, 445, 443, 441, 2219, 438, 2216, 435, 2212, 460, 454, 475, 1517, 1515, 1512, 2447, 798,
+ 797, 2422, 2419, 770, 768, 766, 2383, 2380, 2376, 721, 719, 717, 714, 731, 1714, 2602, 2582, 2580, 2548, 2546,
+ 2543, 923, 921, 2717, 2706, 2705, 2683, 2682, 2680, 1771, 1752, 1750, 1733, 1732, 1731, 1735, 1814, 1707, 1670,
+ 1668, 1631, 1629, 1626, 1634, 1599, 1598, 1596, 1594, 1603, 1601, 2326, 1772, 1753, 1751, 1581, 1554, 1552, 1504,
+ 1501, 1498, 1509, 1442, 1437, 1434, 401, 1448, 1445, 2206, 1392, 1391, 1389, 1387, 1384, 359, 1399, 1397, 1394,
+ 1404, 2171, 2170, 1708, 1672, 1669, 619, 1632, 1630, 1628, 1773, 1378, 1363, 1361, 1333, 1328, 1336, 1286, 1281,
+ 1278, 248, 1292, 1289, 2111, 1218, 1216, 1210, 197, 1206, 193, 1228, 1225, 1221, 1236, 2073, 2071, 1151, 1150,
+ 1148, 1146, 152, 1143, 149, 1140, 145, 1161, 1159, 1156, 1153, 158, 1169, 1166, 2017, 2016, 2014, 2019, 1582,
+ 510, 1556, 1553, 452, 448, 1506, 1500, 394, 391, 387, 1443, 1441, 1439, 1436, 1450, 2207, 765, 716, 713, 1709,
+ 662, 660, 657, 1673, 1671, 916, 914, 879, 878, 877, 882, 1135, 1134, 1121, 1120, 1118, 1123, 1097, 1096, 1094,
+ 1092, 103, 1101, 1099, 1979, 1059, 1058, 1056, 1054, 77, 1051, 74, 1066, 1064, 1061, 1071, 1964, 1963, 1007,
+ 1006, 1004, 1002, 999, 41, 996, 37, 1017, 1015, 1012, 1009, 52, 1025, 1022, 1936, 1935, 1933, 1938, 942, 940,
+ 938, 935, 932, 5, 2, 955, 953, 950, 947, 18, 943, 15, 965, 962, 958, 1895, 1894, 1892, 1890, 973, 1899, 1897,
+ 1379, 325, 1364, 1362, 288, 285, 1334, 1332, 1330, 241, 238, 234, 1287, 1285, 1283, 1280, 1294, 2112, 188, 185,
+ 181, 178, 2028, 1219, 1217, 1215, 1212, 200, 1209, 1227, 2074, 2072, 583, 553, 551, 1583, 505, 503, 500, 513,
+ 1557, 1555, 444, 442, 439, 436, 2213, 455, 451, 1507, 1505, 1502, 796, 763, 762, 760, 767, 711, 710, 708, 706,
+ 2377, 718, 715, 1710, 2544, 917, 915, 2681, 1627, 1597, 1595, 2325, 1769, 1749, 1747, 1499, 1438, 1435, 2204,
+ 1390, 1388, 1385, 1395, 2169, 2167, 1704, 1665, 1662, 1625, 1623, 1620, 1770, 1329, 1282, 1279, 2109, 1214, 1207,
+ 1222, 2068, 2065, 1149, 1147, 1144, 1141, 146, 1157, 1154, 2013, 2011, 2008, 2015, 1579, 1549, 1546, 1495, 1487,
+ 1433, 1431, 1428, 1425, 388, 1440, 2205, 1705, 658, 1667, 1664, 1119, 1095, 1093, 1978, 1057, 1055, 1052, 1062,
+ 1962, 1960, 1005, 1003, 1000, 997, 38, 1013, 1010, 1932, 1930, 1927, 1934, 941, 939, 936, 933, 6, 930, 3, 951,
+ 948, 944, 1889, 1887, 1884, 1881, 959, 1893, 1891, 35, 1377, 1360, 1358, 1327, 1325, 1322, 1331, 1277, 1275,
+ 1272, 1269, 235, 1284, 2110, 1205, 1204, 1201, 1198, 182, 1195, 179, 1213, 2070, 2067, 1580, 501, 1551, 1548,
+ 440, 437, 1497, 1494, 1490, 1503, 761, 709, 707, 1706, 913, 912, 2198, 1386, 2164, 2161, 1621, 1766, 2103, 1208,
+ 2058, 2054, 1145, 1142, 2005, 2002, 1999, 2009, 1488, 1429, 1426, 2200, 1698, 1659, 1656, 1975, 1053, 1957, 1954,
+ 1001, 998, 1924, 1921, 1918, 1928, 937, 934, 931, 1879, 1876, 1873, 1870, 945, 1885, 1882, 1323, 1273, 1270,
+ 2105, 1202, 1199, 1196, 1211, 2061, 2057, 1576, 1543, 1540, 1484, 1481, 1478, 1491, 1700]);
}
diff --git a/src/core/pdf417/PDF417Reader.ts b/src/core/pdf417/PDF417Reader.ts
index 55c78450..7f2d9548 100644
--- a/src/core/pdf417/PDF417Reader.ts
+++ b/src/core/pdf417/PDF417Reader.ts
@@ -61,9 +61,9 @@ import { int } from '../../customTypings';
*
* @author Guenther Grau
*/
-export default /*public final*/ class PDF417Reader implements Reader, MultipleBarcodeReader {
+export default /* public final */ class PDF417Reader implements Reader, MultipleBarcodeReader {
- // private static /*final Result[]*/ EMPTY_RESULT_ARRAY: Result[] = new Result([0]);
+ // private static /*final Result[] */ EMPTY_RESULT_ARRAY: Result[] = new Result([0]);
/**
* Locates and decodes a PDF417 code in an image.
@@ -72,8 +72,8 @@ export default /*public final*/ class PDF417Reader implements Reader, MultipleBa
* @throws NotFoundException if a PDF417 code cannot be found,
* @throws FormatException if a PDF417 cannot be decoded
* @throws ChecksumException
+ * @override decode
*/
- // @Override
public decode(image: BinaryBitmap, hints: Map = null): Result {
let result = PDF417Reader.decode(image, hints, false);
if (result == null || result.length === 0 || result[0] == null) {
@@ -82,14 +82,43 @@ export default /*public final*/ class PDF417Reader implements Reader, MultipleBa
return result[0];
}
+ /**
+ *
+ * @override decodeMultiple
+ */
+ public decodeMultiple(image: BinaryBitmap): Result[];
/**
*
* @param BinaryBitmap
* @param image
* @throws NotFoundException
+ * @override
*/
- // @Override
public decodeMultiple(image: BinaryBitmap, hints: Map = null): Result[] {
+
+ if (!hints) {
+ return this.decodeMultipleOverload1(image);
+ }
+
+ return this.decodeMultipleImpl(image, hints);
+ }
+
+ /**
+ *
+ * @override decodeMultiple
+ */
+ private decodeMultipleOverload1(image: BinaryBitmap): Result[] {
+ return this.decodeMultipleImpl(image, null);
+ }
+
+ /**
+ *
+ * @param BinaryBitmap
+ * @param image
+ * @throws NotFoundException
+ * @override
+ */
+ private decodeMultipleImpl(image: BinaryBitmap, hints: Map = null): Result[] {
try {
return PDF417Reader.decode(image, hints, true);
} catch (ignored) {
@@ -110,14 +139,14 @@ export default /*public final*/ class PDF417Reader implements Reader, MultipleBa
* @throws NotFoundException
* @throws FormatExceptionß
* @throws ChecksumException
- */
+ */
private static decode(image: BinaryBitmap, hints: Map, multiple: boolean) {
const results = new Array();
const detectorResult = Detector.detectMultiple(image, hints, multiple);
for (const points of detectorResult.getPoints()) {
const decoderResult = PDF417ScanningDecoder.decode(detectorResult.getBits(), points[4], points[5],
points[6], points[7], PDF417Reader.getMinCodewordWidth(points), PDF417Reader.getMaxCodewordWidth(points));
- const result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), undefined, points, BarcodeFormat.PDF_417);
+ const result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.PDF_417);
result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult.getECLevel());
const pdf417ResultMetadata: PDF417ResultMetadata = decoderResult.getOther();
if (pdf417ResultMetadata != null) {
@@ -128,21 +157,21 @@ export default /*public final*/ class PDF417Reader implements Reader, MultipleBa
return results.map(x => x);
}
- private static getMaxWidth(p1: ResultPoint, p2: ResultPoint): number /*int*/ {
+ private static getMaxWidth(p1: ResultPoint, p2: ResultPoint): number /* int */ {
if (p1 == null || p2 == null) {
return 0;
}
- return Math.trunc(Math.abs(p1.getX() - p2.getX()));
+ return Math.trunc(Math.abs(p1.getX() - p2.getX()));
}
- private static getMinWidth(p1: ResultPoint, p2: ResultPoint): number /*int*/ {
+ private static getMinWidth(p1: ResultPoint, p2: ResultPoint): number /* int */ {
if (p1 == null || p2 == null) {
return Integer.MAX_VALUE;
}
- return Math.trunc(Math.abs(p1.getX() - p2.getX()));
+ return Math.trunc(Math.abs(p1.getX() - p2.getX()));
}
- private static getMaxCodewordWidth(p: ResultPoint[]): number /*int*/ {
+ private static getMaxCodewordWidth(p: ResultPoint[]): number /* int */ {
return Math.floor(Math.max(
Math.max(PDF417Reader.getMaxWidth(p[0], p[4]), PDF417Reader.getMaxWidth(p[6], p[2]) * PDF417Common.MODULES_IN_CODEWORD /
PDF417Common.MODULES_IN_STOP_PATTERN),
@@ -150,7 +179,7 @@ export default /*public final*/ class PDF417Reader implements Reader, MultipleBa
PDF417Common.MODULES_IN_STOP_PATTERN)));
}
- private static getMinCodewordWidth(p: ResultPoint[]): number /*int*/ {
+ private static getMinCodewordWidth(p: ResultPoint[]): number /* int */ {
return Math.floor(Math.min(
Math.min(PDF417Reader.getMinWidth(p[0], p[4]), PDF417Reader.getMinWidth(p[6], p[2]) * PDF417Common.MODULES_IN_CODEWORD /
PDF417Common.MODULES_IN_STOP_PATTERN),
diff --git a/src/core/pdf417/PDF417ResultMetadata.ts b/src/core/pdf417/PDF417ResultMetadata.ts
index f6d9744e..e4aa5e94 100644
--- a/src/core/pdf417/PDF417ResultMetadata.ts
+++ b/src/core/pdf417/PDF417ResultMetadata.ts
@@ -19,153 +19,153 @@
/**
* @author Guenther Grau
*/
-export default /*public final*/ class PDF417ResultMetadata {
-
- private segmentIndex: /*int*/ number;
- private fileId: string;
- private lastSegment: boolean;
- private segmentCount: /*int*/ number = -1;
- private sender: string;
- private addressee: string;
- private fileName: string;
- private fileSize: /*long*/ number = -1;
- private timestamp: /*long*/ number = -1;
- private checksum: /*int*/ number = -1;
- private optionalData: Int32Array;
-
- /**
- * The Segment ID represents the segment of the whole file distributed over different symbols.
- *
- * @return File segment index
- */
- public getSegmentIndex(): /*int*/ number {
- return this.segmentIndex;
- }
-
- public setSegmentIndex(segmentIndex: /*int*/ number): void {
- this.segmentIndex = segmentIndex;
- }
-
- /**
- * Is the same for each related PDF417 symbol
- *
- * @return File ID
- */
- public getFileId(): string {
- return this.fileId;
- }
-
- public setFileId(fileId: string): void {
- this.fileId = fileId;
- }
-
- /**
- * @return always null
- * @deprecated use dedicated already parsed fields
- */
- // @Deprecated
- public getOptionalData(): Int32Array {
- return this.optionalData;
- }
-
- /**
- * @param optionalData old optional data format as int array
- * @deprecated parse and use new fields
- */
- // @Deprecated
- public setOptionalData(optionalData: Int32Array): void {
- this.optionalData = optionalData;
- }
-
-
- /**
- * @return true if it is the last segment
- */
- public isLastSegment(): boolean {
- return this.lastSegment;
- }
-
- public setLastSegment(lastSegment: boolean): void {
- this.lastSegment = lastSegment;
- }
-
- /**
- * @return count of segments, -1 if not set
- */
- public getSegmentCount(): /*int*/ number {
- return this.segmentCount;
- }
-
- public setSegmentCount(segmentCount: number /*int*/): void {
- this.segmentCount = segmentCount;
- }
-
- public getSender(): string {
- return this.sender || null;
- }
-
- public setSender(sender: string): void {
- this.sender = sender;
- }
-
- public getAddressee(): string {
- return this.addressee || null;
- }
-
- public setAddressee(addressee: string): void {
- this.addressee = addressee;
- }
-
- /**
- * Filename of the encoded file
- *
- * @return filename
- */
- public getFileName(): string {
- return this.fileName;
- }
-
- public setFileName(fileName: string): void {
- this.fileName = fileName;
- }
-
- /**
- * filesize in bytes of the encoded file
- *
- * @return filesize in bytes, -1 if not set
- */
- public getFileSize(): /*long*/ number {
- return this.fileSize;
- }
-
- public setFileSize(fileSize: number /*long*/): void {
- this.fileSize = fileSize;
- }
-
- /**
- * 16-bit CRC checksum using CCITT-16
- *
- * @return crc checksum, -1 if not set
- */
- public getChecksum(): /*int*/ number {
- return this.checksum;
- }
-
- public setChecksum(checksum: number/*int*/): void {
- this.checksum = checksum;
- }
-
- /**
- * unix epock timestamp, elapsed seconds since 1970-01-01
- *
- * @return elapsed seconds, -1 if not set
- */
- public getTimestamp(): /*long*/ number {
- return this.timestamp;
- }
-
- public setTimestamp(timestamp: number /*long*/): void {
- this.timestamp = timestamp;
- }
+export default /* public final */ class PDF417ResultMetadata {
+
+ private segmentIndex: /* int */ number;
+ private fileId: string;
+ private lastSegment: boolean;
+ private segmentCount: /* int */ number = -1;
+ private sender: string;
+ private addressee: string;
+ private fileName: string;
+ private fileSize: /* long */ number = -1;
+ private timestamp: /* long */ number = -1;
+ private checksum: /* int */ number = -1;
+ private optionalData: Int32Array;
+
+ /**
+ * The Segment ID represents the segment of the whole file distributed over different symbols.
+ *
+ * @return File segment index
+ */
+ public getSegmentIndex(): /* int */ number {
+ return this.segmentIndex;
+ }
+
+ public setSegmentIndex(segmentIndex: /* int */ number): void {
+ this.segmentIndex = segmentIndex;
+ }
+
+ /**
+ * Is the same for each related PDF417 symbol
+ *
+ * @return File ID
+ */
+ public getFileId(): string {
+ return this.fileId;
+ }
+
+ public setFileId(fileId: string): void {
+ this.fileId = fileId;
+ }
+
+ /**
+ * @return always null
+ * @deprecated use dedicated already parsed fields
+ */
+ // @Deprecated
+ public getOptionalData(): Int32Array {
+ return this.optionalData;
+ }
+
+ /**
+ * @param optionalData old optional data format as int array
+ * @deprecated parse and use new fields
+ */
+ // @Deprecated
+ public setOptionalData(optionalData: Int32Array): void {
+ this.optionalData = optionalData;
+ }
+
+
+ /**
+ * @return true if it is the last segment
+ */
+ public isLastSegment(): boolean {
+ return this.lastSegment;
+ }
+
+ public setLastSegment(lastSegment: boolean): void {
+ this.lastSegment = lastSegment;
+ }
+
+ /**
+ * @return count of segments, -1 if not set
+ */
+ public getSegmentCount(): /* int */ number {
+ return this.segmentCount;
+ }
+
+ public setSegmentCount(segmentCount: number /* int */): void {
+ this.segmentCount = segmentCount;
+ }
+
+ public getSender(): string {
+ return this.sender || null;
+ }
+
+ public setSender(sender: string): void {
+ this.sender = sender;
+ }
+
+ public getAddressee(): string {
+ return this.addressee || null;
+ }
+
+ public setAddressee(addressee: string): void {
+ this.addressee = addressee;
+ }
+
+ /**
+ * Filename of the encoded file
+ *
+ * @return filename
+ */
+ public getFileName(): string {
+ return this.fileName;
+ }
+
+ public setFileName(fileName: string): void {
+ this.fileName = fileName;
+ }
+
+ /**
+ * filesize in bytes of the encoded file
+ *
+ * @return filesize in bytes, -1 if not set
+ */
+ public getFileSize(): /* long */ number {
+ return this.fileSize;
+ }
+
+ public setFileSize(fileSize: number /* long */): void {
+ this.fileSize = fileSize;
+ }
+
+ /**
+ * 16-bit CRC checksum using CCITT-16
+ *
+ * @return crc checksum, -1 if not set
+ */
+ public getChecksum(): /* int */ number {
+ return this.checksum;
+ }
+
+ public setChecksum(checksum: number/* int */): void {
+ this.checksum = checksum;
+ }
+
+ /**
+ * unix epock timestamp, elapsed seconds since 1970-01-01
+ *
+ * @return elapsed seconds, -1 if not set
+ */
+ public getTimestamp(): /* long */ number {
+ return this.timestamp;
+ }
+
+ public setTimestamp(timestamp: number /* long */): void {
+ this.timestamp = timestamp;
+ }
}
diff --git a/src/core/pdf417/decoder/BarcodeMetadata.ts b/src/core/pdf417/decoder/BarcodeMetadata.ts
index a348b160..d4eb6e0d 100644
--- a/src/core/pdf417/decoder/BarcodeMetadata.ts
+++ b/src/core/pdf417/decoder/BarcodeMetadata.ts
@@ -21,13 +21,13 @@ import { int } from '../../../customTypings';
/**
* @author Guenther Grau
*/
-export default /*final*/ class BarcodeMetadata {
+export default /* final */ class BarcodeMetadata {
- private /*final*/ columnCount: int;
- private /*final*/ errorCorrectionLevel: int;
- private /*final*/ rowCountUpperPart: int;
- private /*final*/ rowCountLowerPart: int;
- private /*final*/ rowCount: int;
+ private /* final */ columnCount: int;
+ private /* final */ errorCorrectionLevel: int;
+ private /* final */ rowCountUpperPart: int;
+ private /* final */ rowCountLowerPart: int;
+ private /* final */ rowCount: int;
constructor(columnCount: int, rowCountUpperPart: int, rowCountLowerPart: int, errorCorrectionLevel: int) {
this.columnCount = columnCount;
diff --git a/src/core/pdf417/decoder/BarcodeValue.ts b/src/core/pdf417/decoder/BarcodeValue.ts
index 8eec779d..f02530a9 100644
--- a/src/core/pdf417/decoder/BarcodeValue.ts
+++ b/src/core/pdf417/decoder/BarcodeValue.ts
@@ -30,13 +30,13 @@ import { int, Collection } from '../../../customTypings';
/**
* @author Guenther Grau
*/
-export default /*final*/ class BarcodeValue {
- private /*final*/ values = new Map();
+export default /* final */ class BarcodeValue {
+ private /* final */ values = new Map();
/**
* Add an occurrence of a value
- */
- setValue(value: int): void {
+ */
+ setValue(value: int): void {
value = Math.trunc(value);
let confidence: int = this.values.get(value);
if (confidence == null) {
@@ -49,8 +49,8 @@ export default /*final*/ class BarcodeValue {
/**
* Determines the maximum occurrence of a set value and returns all values which were set with this occurrence.
* @return an array of int, containing the values with the highest occurrence, or null, if no value was set
- */
- getValue(): Int32Array {
+ */
+ getValue(): Int32Array {
let maxConfidence: int = -1;
let result: Collection = new Array();
for (const [key, value] of this.values.entries()) {
@@ -71,7 +71,7 @@ export default /*final*/ class BarcodeValue {
return PDF417Common.toIntArray(result);
}
- getConfidence(value: int): int {
+ getConfidence(value: int): int {
return this.values.get(value);
}
diff --git a/src/core/pdf417/decoder/BoundingBox.ts b/src/core/pdf417/decoder/BoundingBox.ts
index cd5014f6..5dca3442 100644
--- a/src/core/pdf417/decoder/BoundingBox.ts
+++ b/src/core/pdf417/decoder/BoundingBox.ts
@@ -27,23 +27,23 @@ import { int } from '../../../customTypings';
/**
* @author Guenther Grau
*/
-export default /*final*/ class BoundingBox {
-
- private /*final*/ image: BitMatrix;
- private /*final*/ topLeft: ResultPoint;
- private /*final*/ bottomLeft: ResultPoint;
- private /*final*/ topRight: ResultPoint;
- private /*final*/ bottomRight: ResultPoint;
- private /*final*/ minX: int;
- private /*final*/ maxX: int;
- private /*final*/ minY: int;
- private /*final*/ maxY: int;
-
- constructor( image: BitMatrix|BoundingBox,
- topLeft?: ResultPoint,
- bottomLeft?: ResultPoint,
- topRight?: ResultPoint,
- bottomRight?: ResultPoint) {
+export default /* final */ class BoundingBox {
+
+ private /* final */ image: BitMatrix;
+ private /* final */ topLeft: ResultPoint;
+ private /* final */ bottomLeft: ResultPoint;
+ private /* final */ topRight: ResultPoint;
+ private /* final */ bottomRight: ResultPoint;
+ private /* final */ minX: int;
+ private /* final */ maxX: int;
+ private /* final */ minY: int;
+ private /* final */ maxY: int;
+
+ constructor(image: BitMatrix | BoundingBox,
+ topLeft?: ResultPoint,
+ bottomLeft?: ResultPoint,
+ topRight?: ResultPoint,
+ bottomRight?: ResultPoint) {
if (image instanceof BoundingBox) {
this.constructor_2(image);
} else {
@@ -60,12 +60,12 @@ export default /*final*/ class BoundingBox {
* @param bottomRight
*
* @throws NotFoundException
- */
- private constructor_1( image: BitMatrix,
- topLeft: ResultPoint,
- bottomLeft: ResultPoint,
- topRight: ResultPoint,
- bottomRight: ResultPoint) {
+ */
+ private constructor_1(image: BitMatrix,
+ topLeft: ResultPoint,
+ bottomLeft: ResultPoint,
+ topRight: ResultPoint,
+ bottomRight: ResultPoint) {
const leftUnspecified = topLeft == null || bottomLeft == null;
const rightUnspecified = topRight == null || bottomRight == null;
if (leftUnspecified && rightUnspecified) {
@@ -83,10 +83,10 @@ export default /*final*/ class BoundingBox {
this.bottomLeft = bottomLeft;
this.topRight = topRight;
this.bottomRight = bottomRight;
- this.minX = Math.trunc(Math.min(topLeft.getX(), bottomLeft.getX()));
- this.maxX = Math.trunc(Math.max(topRight.getX(), bottomRight.getX()));
- this.minY = Math.trunc(Math.min(topLeft.getY(), topRight.getY()));
- this.maxY = Math.trunc(Math.max(bottomLeft.getY(), bottomRight.getY()));
+ this.minX = Math.trunc(Math.min(topLeft.getX(), bottomLeft.getX()));
+ this.maxX = Math.trunc(Math.max(topRight.getX(), bottomRight.getX()));
+ this.minY = Math.trunc(Math.min(topLeft.getY(), topRight.getY()));
+ this.maxY = Math.trunc(Math.max(bottomLeft.getY(), bottomRight.getY()));
}
private constructor_2(boundingBox: BoundingBox) {
@@ -103,8 +103,8 @@ export default /*final*/ class BoundingBox {
/**
* @throws NotFoundException
- */
- static merge( leftBox: BoundingBox, rightBox: BoundingBox): BoundingBox {
+ */
+ static merge(leftBox: BoundingBox, rightBox: BoundingBox): BoundingBox {
if (leftBox == null) {
return rightBox;
}
@@ -116,7 +116,7 @@ export default /*final*/ class BoundingBox {
/**
* @throws NotFoundException
- */
+ */
addMissingRows(missingStartRows: int, missingEndRows: int, isLeft: boolean): BoundingBox {
let newTopLeft: ResultPoint = this.topLeft;
let newBottomLeft: ResultPoint = this.bottomLeft;
@@ -125,7 +125,7 @@ export default /*final*/ class BoundingBox {
if (missingStartRows > 0) {
let top: ResultPoint = isLeft ? this.topLeft : this.topRight;
- let newMinY: int = Math.trunc(top.getY() - missingStartRows);
+ let newMinY: int = Math.trunc(top.getY() - missingStartRows);
if (newMinY < 0) {
newMinY = 0;
}
@@ -139,7 +139,7 @@ export default /*final*/ class BoundingBox {
if (missingEndRows > 0) {
let bottom: ResultPoint = isLeft ? this.bottomLeft : this.bottomRight;
- let newMaxY: int = Math.trunc(bottom.getY() + missingEndRows);
+ let newMaxY: int = Math.trunc(bottom.getY() + missingEndRows);
if (newMaxY >= this.image.getHeight()) {
newMaxY = this.image.getHeight() - 1;
}
@@ -170,19 +170,19 @@ export default /*final*/ class BoundingBox {
return this.maxY;
}
- getTopLeft(): ResultPoint {
+ getTopLeft(): ResultPoint {
return this.topLeft;
}
- getTopRight(): ResultPoint {
+ getTopRight(): ResultPoint {
return this.topRight;
}
- getBottomLeft(): ResultPoint {
+ getBottomLeft(): ResultPoint {
return this.bottomLeft;
}
- getBottomRight(): ResultPoint {
+ getBottomRight(): ResultPoint {
return this.bottomRight;
}
diff --git a/src/core/pdf417/decoder/Codeword.ts b/src/core/pdf417/decoder/Codeword.ts
index 6b2118fa..549df5e1 100644
--- a/src/core/pdf417/decoder/Codeword.ts
+++ b/src/core/pdf417/decoder/Codeword.ts
@@ -21,14 +21,14 @@ import { int } from '../../../customTypings';
/**
* @author Guenther Grau
*/
-export default /*final*/ class Codeword {
+export default /* final */ class Codeword {
- private static /*final*/ BARCODE_ROW_UNKNOWN: int = -1;
+ private static /* final */ BARCODE_ROW_UNKNOWN: int = -1;
- private /*final*/ startX: int;
- private /*final*/ endX: int;
- private /*final*/ bucket: int;
- private /*final*/ value: int;
+ private /* final */ startX: int;
+ private /* final */ endX: int;
+ private /* final */ bucket: int;
+ private /* final */ value: int;
private rowNumber: int = Codeword.BARCODE_ROW_UNKNOWN;
constructor(startX: int, endX: int, bucket: int, value: int) {
@@ -74,12 +74,12 @@ export default /*final*/ class Codeword {
return this.rowNumber;
}
- setRowNumber(rowNumber: int ): void {
+ setRowNumber(rowNumber: int): void {
this.rowNumber = rowNumber;
}
-// @Override
- public toString(): string {
+ // @Override
+ public toString(): string {
return this.rowNumber + '|' + this.value;
}
diff --git a/src/core/pdf417/decoder/DecodedBitStreamParser.ts b/src/core/pdf417/decoder/DecodedBitStreamParser.ts
index 9ab6c519..3dbf552f 100644
--- a/src/core/pdf417/decoder/DecodedBitStreamParser.ts
+++ b/src/core/pdf417/decoder/DecodedBitStreamParser.ts
@@ -41,7 +41,7 @@ import StringEncoding from '../../util/StringEncoding';
import { int } from '../../../customTypings';
-/*private*/ enum Mode {
+/* private */ enum Mode {
ALPHA,
LOWER,
MIXED,
@@ -107,7 +107,7 @@ function getEXP900(): bigint[] {
EXP900[1] = nineHundred;
// in Java - array with length = 16
- for (let i /*int*/ = 2; i < 16; i++) {
+ for (let i /* int */ = 2; i < 16; i++) {
EXP900[i] = EXP900[i - 1] * nineHundred;
}
@@ -120,50 +120,50 @@ function getEXP900(): bigint[] {
* @author SITA Lab (kevin.osullivan@sita.aero)
* @author Guenther Grau
*/
-export default /*final*/ class DecodedBitStreamParser {
-
- private static /*final*/ TEXT_COMPACTION_MODE_LATCH: int = 900;
- private static /*final*/ BYTE_COMPACTION_MODE_LATCH: int = 901;
- private static /*final*/ NUMERIC_COMPACTION_MODE_LATCH: int = 902;
- private static /*final*/ BYTE_COMPACTION_MODE_LATCH_6: int = 924;
- private static /*final*/ ECI_USER_DEFINED: int = 925;
- private static /*final*/ ECI_GENERAL_PURPOSE: int = 926;
- private static /*final*/ ECI_CHARSET: int = 927;
- private static /*final*/ BEGIN_MACRO_PDF417_CONTROL_BLOCK: int = 928;
- private static /*final*/ BEGIN_MACRO_PDF417_OPTIONAL_FIELD: int = 923;
- private static /*final*/ MACRO_PDF417_TERMINATOR: int = 922;
- private static /*final*/ MODE_SHIFT_TO_BYTE_COMPACTION_MODE: int = 913;
- private static /*final*/ MAX_NUMERIC_CODEWORDS: int = 15;
-
- private static /*final*/ MACRO_PDF417_OPTIONAL_FIELD_FILE_NAME: int = 0;
- private static /*final*/ MACRO_PDF417_OPTIONAL_FIELD_SEGMENT_COUNT: int = 1;
- private static /*final*/ MACRO_PDF417_OPTIONAL_FIELD_TIME_STAMP: int = 2;
- private static /*final*/ MACRO_PDF417_OPTIONAL_FIELD_SENDER: int = 3;
- private static /*final*/ MACRO_PDF417_OPTIONAL_FIELD_ADDRESSEE: int = 4;
- private static /*final*/ MACRO_PDF417_OPTIONAL_FIELD_FILE_SIZE: int = 5;
- private static /*final*/ MACRO_PDF417_OPTIONAL_FIELD_CHECKSUM: int = 6;
-
- private static /*final*/ PL: int = 25;
- private static /*final*/ LL: int = 27;
- private static /*final*/ AS: int = 27;
- private static /*final*/ ML: int = 28;
- private static /*final*/ AL: int = 28;
- private static /*final*/ PS: int = 29;
- private static /*final*/ PAL: int = 29;
-
- private static /*final*/ PUNCT_CHARS: string =
- ';<>@[\\]_`~!\r\t,:\n-.$/"|*()?{}\'';
-
- private static /*final*/ MIXED_CHARS: string =
- '0123456789&\r\t,:#-.$/+%*=^';
+export default /* final */ class DecodedBitStreamParser {
+
+ private static /* final */ TEXT_COMPACTION_MODE_LATCH: int = 900;
+ private static /* final */ BYTE_COMPACTION_MODE_LATCH: int = 901;
+ private static /* final */ NUMERIC_COMPACTION_MODE_LATCH: int = 902;
+ private static /* final */ BYTE_COMPACTION_MODE_LATCH_6: int = 924;
+ private static /* final */ ECI_USER_DEFINED: int = 925;
+ private static /* final */ ECI_GENERAL_PURPOSE: int = 926;
+ private static /* final */ ECI_CHARSET: int = 927;
+ private static /* final */ BEGIN_MACRO_PDF417_CONTROL_BLOCK: int = 928;
+ private static /* final */ BEGIN_MACRO_PDF417_OPTIONAL_FIELD: int = 923;
+ private static /* final */ MACRO_PDF417_TERMINATOR: int = 922;
+ private static /* final */ MODE_SHIFT_TO_BYTE_COMPACTION_MODE: int = 913;
+ private static /* final */ MAX_NUMERIC_CODEWORDS: int = 15;
+
+ private static /* final */ MACRO_PDF417_OPTIONAL_FIELD_FILE_NAME: int = 0;
+ private static /* final */ MACRO_PDF417_OPTIONAL_FIELD_SEGMENT_COUNT: int = 1;
+ private static /* final */ MACRO_PDF417_OPTIONAL_FIELD_TIME_STAMP: int = 2;
+ private static /* final */ MACRO_PDF417_OPTIONAL_FIELD_SENDER: int = 3;
+ private static /* final */ MACRO_PDF417_OPTIONAL_FIELD_ADDRESSEE: int = 4;
+ private static /* final */ MACRO_PDF417_OPTIONAL_FIELD_FILE_SIZE: int = 5;
+ private static /* final */ MACRO_PDF417_OPTIONAL_FIELD_CHECKSUM: int = 6;
+
+ private static /* final */ PL: int = 25;
+ private static /* final */ LL: int = 27;
+ private static /* final */ AS: int = 27;
+ private static /* final */ ML: int = 28;
+ private static /* final */ AL: int = 28;
+ private static /* final */ PS: int = 29;
+ private static /* final */ PAL: int = 29;
+
+ private static /* final */ PUNCT_CHARS: string =
+ ';<>@[\\]_`~!\r\t,:\n-.$/"|*()?{}\'';
+
+ private static /* final */ MIXED_CHARS: string =
+ '0123456789&\r\t,:#-.$/+%*=^';
/**
* Table containing values for the exponent of 900.
* This is used in the numeric compaction decode algorithm.
- */
- private static /*final*/ EXP900: bigint[] = getBigIntConstructor() ? getEXP900() : [];
+ */
+ private static /* final */ EXP900: bigint[] = getBigIntConstructor() ? getEXP900() : [];
- private static /*final*/ NUMBER_OF_SEQUENCE_CODEWORDS: int = 2;
+ private static /* final */ NUMBER_OF_SEQUENCE_CODEWORDS: int = 2;
// private DecodedBitStreamParser() {
// }
@@ -174,7 +174,7 @@ export default /*final*/ class DecodedBitStreamParser {
* @param ecLevel
*
* @throws FormatException
- */
+ */
static decode(codewords: Int32Array, ecLevel: string): DecoderResult {
// pass encoding to result (will be used for decode symbols in byte mode)
let result: StringBuilder = new StringBuilder('');
@@ -186,7 +186,7 @@ export default /*final*/ class DecodedBitStreamParser {
* convert it to string later correctly due to encoding
* differences from Java version. As reported here:
* https://github.com/zxing-js/library/pull/264/files#r382831593
- */
+ */
result.enableDecoding(encoding);
// Get compaction mode
let codeIndex: int = 1;
@@ -202,7 +202,7 @@ export default /*final*/ class DecodedBitStreamParser {
codeIndex = DecodedBitStreamParser.byteCompaction(code, codewords, encoding, codeIndex, result);
break;
case DecodedBitStreamParser.MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
- result.append(/*(char)*/ codewords[codeIndex++]);
+ result.append(/* (char) */ codewords[codeIndex++]);
break;
case DecodedBitStreamParser.NUMERIC_COMPACTION_MODE_LATCH:
codeIndex = DecodedBitStreamParser.numericCompaction(codewords, codeIndex, result);
@@ -260,7 +260,7 @@ export default /*final*/ class DecodedBitStreamParser {
* @param resultMetadata
*
* @throws FormatException
- */
+ */
// @SuppressWarnings("deprecation")
static decodeMacroBlock(codewords: Int32Array, codeIndex: int, resultMetadata: PDF417ResultMetadata): int {
if (codeIndex + DecodedBitStreamParser.NUMBER_OF_SEQUENCE_CODEWORDS > codewords[0]) {
@@ -268,7 +268,7 @@ export default /*final*/ class DecodedBitStreamParser {
throw FormatException.getFormatInstance();
}
let segmentIndexArray: Int32Array = new Int32Array(DecodedBitStreamParser.NUMBER_OF_SEQUENCE_CODEWORDS);
- for (let i /*int*/ = 0; i < DecodedBitStreamParser.NUMBER_OF_SEQUENCE_CODEWORDS; i++, codeIndex++) {
+ for (let i /* int */ = 0; i < DecodedBitStreamParser.NUMBER_OF_SEQUENCE_CODEWORDS; i++, codeIndex++) {
segmentIndexArray[i] = codewords[codeIndex];
}
resultMetadata.setSegmentIndex(Integer.parseInt(DecodedBitStreamParser.decodeBase900toBase10(segmentIndexArray,
@@ -358,7 +358,7 @@ export default /*final*/ class DecodedBitStreamParser {
* @param codeIndex The current index into the codeword array.
* @param result The decoded data is appended to the result.
* @return The next index into the codeword array.
- */
+ */
private static textCompaction(codewords: Int32Array, codeIndex: int, result: StringBuilder): int {
// 2 character per codeword
let textCompactionData: Int32Array = new Int32Array((codewords[0] - codeIndex) * 2);
@@ -422,7 +422,7 @@ export default /*final*/ class DecodedBitStreamParser {
* was a mode shift.
* @param length The size of the text compaction and byte compaction data.
* @param result The decoded data is appended to the result.
- */
+ */
private static decodeTextCompaction(textCompactionData: Int32Array,
byteCompactionData: Int32Array,
length: int,
@@ -436,14 +436,14 @@ export default /*final*/ class DecodedBitStreamParser {
let i: int = 0;
while (i < length) {
let subModeCh: int = textCompactionData[i];
- let ch: /*char*/ string = '';
+ let ch: /* char */ string = '';
switch (subMode) {
case Mode.ALPHA:
// Alpha (alphabetic: uppercase)
if (subModeCh < 26) {
// Upper case Alpha Character
// Note: 65 = 'A' ASCII -> there is byte code of symbol
- ch = /*(char)('A' + subModeCh) */ String.fromCharCode(65 + subModeCh);
+ ch = /* (char)('A' + subModeCh) */ String.fromCharCode(65 + subModeCh);
} else {
switch (subModeCh) {
case 26:
@@ -461,7 +461,7 @@ export default /*final*/ class DecodedBitStreamParser {
subMode = Mode.PUNCT_SHIFT;
break;
case DecodedBitStreamParser.MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
- result.append(/*(char)*/ byteCompactionData[i]);
+ result.append(/* (char) */ byteCompactionData[i]);
break;
case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
subMode = Mode.ALPHA;
@@ -473,7 +473,7 @@ export default /*final*/ class DecodedBitStreamParser {
case Mode.LOWER:
// Lower (alphabetic: lowercase)
if (subModeCh < 26) {
- ch = /*(char)('a' + subModeCh)*/String.fromCharCode(97 + subModeCh);
+ ch = /* (char)('a' + subModeCh) */String.fromCharCode(97 + subModeCh);
} else {
switch (subModeCh) {
case 26:
@@ -494,7 +494,7 @@ export default /*final*/ class DecodedBitStreamParser {
break;
case DecodedBitStreamParser.MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
// TODO Does this need to use the current character encoding? See other occurrences below
- result.append(/*(char)*/ byteCompactionData[i]);
+ result.append(/* (char) */ byteCompactionData[i]);
break;
case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
subMode = Mode.ALPHA;
@@ -527,7 +527,7 @@ export default /*final*/ class DecodedBitStreamParser {
subMode = Mode.PUNCT_SHIFT;
break;
case DecodedBitStreamParser.MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
- result.append(/*(char)*/ byteCompactionData[i]);
+ result.append(/* (char) */ byteCompactionData[i]);
break;
case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
subMode = Mode.ALPHA;
@@ -546,7 +546,7 @@ export default /*final*/ class DecodedBitStreamParser {
subMode = Mode.ALPHA;
break;
case DecodedBitStreamParser.MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
- result.append(/*(char)*/ byteCompactionData[i]);
+ result.append(/* (char) */ byteCompactionData[i]);
break;
case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
subMode = Mode.ALPHA;
@@ -559,7 +559,7 @@ export default /*final*/ class DecodedBitStreamParser {
// Restore sub-mode
subMode = priorToShiftMode;
if (subModeCh < 26) {
- ch = /*(char)('A' + subModeCh)*/ String.fromCharCode(65 + subModeCh);
+ ch = /* (char)('A' + subModeCh) */ String.fromCharCode(65 + subModeCh);
} else {
switch (subModeCh) {
case 26:
@@ -585,7 +585,7 @@ export default /*final*/ class DecodedBitStreamParser {
case DecodedBitStreamParser.MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
// PS before Shift-to-Byte is used as a padding character,
// see 5.4.2.4 of the specification
- result.append(/*(char)*/ byteCompactionData[i]);
+ result.append(/* (char) */ byteCompactionData[i]);
break;
case DecodedBitStreamParser.TEXT_COMPACTION_MODE_LATCH:
subMode = Mode.ALPHA;
@@ -614,15 +614,15 @@ export default /*final*/ class DecodedBitStreamParser {
* @param codeIndex The current index into the codeword array.
* @param result The decoded data is appended to the result.
* @return The next index into the codeword array.
- */
- private static /*int*/ byteCompaction(mode: int,
+ */
+ private static /* int */ byteCompaction(mode: int,
codewords: Int32Array,
- encoding: /*Charset*/ CharacterSetECI,
+ encoding: /* Charset */ CharacterSetECI,
codeIndex: int,
result: StringBuilder) {
let decodedBytes: ByteArrayOutputStream = new ByteArrayOutputStream();
let count: int = 0;
- let value: /*long*/ number = 0;
+ let value: /* long */ number = 0;
let end: boolean = false;
switch (mode) {
@@ -653,12 +653,12 @@ export default /*final*/ class DecodedBitStreamParser {
if ((count % 5 === 0) && (count > 0)) {
// Decode every 5 codewords
// Convert to Base 256
- for (let j /*int*/ = 0; j < 6; ++j) {
+ for (let j /* int */ = 0; j < 6; ++j) {
/* @note
* JavaScript stores numbers as 64 bits floating point numbers, but all bitwise operations are performed on 32 bits binary numbers.
* So the next bitwise operation could not be done with simple numbers
- */
- decodedBytes.write(/*(byte)*/Number(createBigInt(value) >> createBigInt(8 * (5 - j))));
+ */
+ decodedBytes.write(/* (byte) */Number(createBigInt(value) >> createBigInt(8 * (5 - j))));
}
value = 0;
count = 0;
@@ -675,8 +675,8 @@ export default /*final*/ class DecodedBitStreamParser {
// If Byte Compaction mode is invoked with codeword 901,
// the last group of codewords is interpreted directly
// as one byte per codeword, without compaction.
- for (let i /*int*/ = 0; i < count; i++) {
- decodedBytes.write(/*(byte)*/ byteCompactedCodewords[i]);
+ for (let i /* int */ = 0; i < count; i++) {
+ decodedBytes.write(/* (byte) */ byteCompactedCodewords[i]);
}
break;
@@ -710,9 +710,9 @@ export default /*final*/ class DecodedBitStreamParser {
/* @note
* JavaScript stores numbers as 64 bits floating point numbers, but all bitwise operations are performed on 32 bits binary numbers.
* So the next bitwise operation could not be done with simple numbers
- */
- for (let j /*int*/ = 0; j < 6; ++j) {
- decodedBytes.write(/*(byte)*/Number(createBigInt(value) >> createBigInt(8 * (5 - j))));
+ */
+ for (let j /* int */ = 0; j < 6; ++j) {
+ decodedBytes.write(/* (byte) */Number(createBigInt(value) >> createBigInt(8 * (5 - j))));
}
value = 0;
count = 0;
@@ -733,8 +733,8 @@ export default /*final*/ class DecodedBitStreamParser {
* @return The next index into the codeword array.
*
* @throws FormatException
- */
- private static numericCompaction(codewords: Int32Array, codeIndex: number /*int*/, result: StringBuilder): int {
+ */
+ private static numericCompaction(codewords: Int32Array, codeIndex: number /* int */, result: StringBuilder): int {
let count: int = 0;
let end: boolean = false;
@@ -816,10 +816,10 @@ export default /*final*/ class DecodedBitStreamParser {
* Remove leading 1 => Result is 000213298174000
*
* @throws FormatException
- */
+ */
private static decodeBase900toBase10(codewords: Int32Array, count: int): string {
let result = createBigInt(0);
- for (let i /*int*/ = 0; i < count; i++) {
+ for (let i /* int */ = 0; i < count; i++) {
result += DecodedBitStreamParser.EXP900[count - i - 1] * createBigInt(codewords[i]);
}
let resultString: String = result.toString();
diff --git a/src/core/pdf417/decoder/DetectionResult.ts b/src/core/pdf417/decoder/DetectionResult.ts
index 3426d049..a5f54238 100644
--- a/src/core/pdf417/decoder/DetectionResult.ts
+++ b/src/core/pdf417/decoder/DetectionResult.ts
@@ -33,14 +33,14 @@ import { int } from '../../../customTypings';
/**
* @author Guenther Grau
*/
-export default /*final*/ class DetectionResult {
+export default /* final */ class DetectionResult {
- /*final*/ ADJUST_ROW_NUMBER_SKIP: int = 2;
+ /* final */ ADJUST_ROW_NUMBER_SKIP: int = 2;
- private /*final*/ barcodeMetadata: BarcodeMetadata;
- private /*final*/ detectionResultColumns: DetectionResultColumn[];
+ private /* final */ barcodeMetadata: BarcodeMetadata;
+ private /* final */ detectionResultColumns: DetectionResultColumn[];
private boundingBox: BoundingBox;
- private /*final*/ barcodeColumnCount: int;
+ private /* final */ barcodeColumnCount: int;
constructor(barcodeMetadata: BarcodeMetadata, boundingBox: BoundingBox) {
this.barcodeMetadata = barcodeMetadata;
@@ -75,15 +75,15 @@ export default /*final*/ class DetectionResult {
/**
* @return number of codewords which don't have a valid row number. Note that the count is not accurate as codewords
* will be counted several times. It just serves as an indicator to see when we can stop adjusting row numbers
- */
+ */
private adjustRowNumbersAndGetCount(): int {
let unadjustedCount: int = this.adjustRowNumbersByRow();
if (unadjustedCount === 0) {
return 0;
}
- for (let barcodeColumn /*int*/ = 1; barcodeColumn < this.barcodeColumnCount + 1; barcodeColumn++) {
+ for (let barcodeColumn /* int */ = 1; barcodeColumn < this.barcodeColumnCount + 1; barcodeColumn++) {
let codewords: Codeword[] = this.detectionResultColumns[barcodeColumn].getCodewords();
- for (let codewordsRow /*int*/ = 0; codewordsRow < codewords.length; codewordsRow++) {
+ for (let codewordsRow /* int */ = 0; codewordsRow < codewords.length; codewordsRow++) {
if (codewords[codewordsRow] == null) {
continue;
}
@@ -111,11 +111,11 @@ export default /*final*/ class DetectionResult {
}
let LRIcodewords: Codeword[] = this.detectionResultColumns[0].getCodewords();
let RRIcodewords: Codeword[] = this.detectionResultColumns[this.barcodeColumnCount + 1].getCodewords();
- for (let codewordsRow /*int*/ = 0; codewordsRow < LRIcodewords.length; codewordsRow++) {
+ for (let codewordsRow /* int */ = 0; codewordsRow < LRIcodewords.length; codewordsRow++) {
if (LRIcodewords[codewordsRow] != null &&
RRIcodewords[codewordsRow] != null &&
LRIcodewords[codewordsRow].getRowNumber() === RRIcodewords[codewordsRow].getRowNumber()) {
- for (let barcodeColumn /*int*/ = 1; barcodeColumn <= this.barcodeColumnCount; barcodeColumn++) {
+ for (let barcodeColumn /* int */ = 1; barcodeColumn <= this.barcodeColumnCount; barcodeColumn++) {
let codeword: Codeword = this.detectionResultColumns[barcodeColumn].getCodewords()[codewordsRow];
if (codeword == null) {
continue;
@@ -135,13 +135,13 @@ export default /*final*/ class DetectionResult {
}
let unadjustedCount: int = 0;
let codewords: Codeword[] = this.detectionResultColumns[this.barcodeColumnCount + 1].getCodewords();
- for (let codewordsRow /*int*/ = 0; codewordsRow < codewords.length; codewordsRow++) {
+ for (let codewordsRow /* int */ = 0; codewordsRow < codewords.length; codewordsRow++) {
if (codewords[codewordsRow] == null) {
continue;
}
let rowIndicatorRowNumber: int = codewords[codewordsRow].getRowNumber();
let invalidRowCounts: int = 0;
- for (let barcodeColumn /*int*/ = this.barcodeColumnCount + 1; barcodeColumn > 0 && invalidRowCounts < this.ADJUST_ROW_NUMBER_SKIP; barcodeColumn--) {
+ for (let barcodeColumn /* int */ = this.barcodeColumnCount + 1; barcodeColumn > 0 && invalidRowCounts < this.ADJUST_ROW_NUMBER_SKIP; barcodeColumn--) {
let codeword: Codeword = this.detectionResultColumns[barcodeColumn].getCodewords()[codewordsRow];
if (codeword != null) {
invalidRowCounts = DetectionResult.adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword);
@@ -160,13 +160,13 @@ export default /*final*/ class DetectionResult {
}
let unadjustedCount: int = 0;
let codewords: Codeword[] = this.detectionResultColumns[0].getCodewords();
- for (let codewordsRow /*int*/ = 0; codewordsRow < codewords.length; codewordsRow++) {
+ for (let codewordsRow /* int */ = 0; codewordsRow < codewords.length; codewordsRow++) {
if (codewords[codewordsRow] == null) {
continue;
}
let rowIndicatorRowNumber: int = codewords[codewordsRow].getRowNumber();
let invalidRowCounts: int = 0;
- for (let barcodeColumn /*int*/ = 1; barcodeColumn < this.barcodeColumnCount + 1 && invalidRowCounts < this.ADJUST_ROW_NUMBER_SKIP; barcodeColumn++) {
+ for (let barcodeColumn /* int */ = 1; barcodeColumn < this.barcodeColumnCount + 1 && invalidRowCounts < this.ADJUST_ROW_NUMBER_SKIP; barcodeColumn++) {
let codeword: Codeword = this.detectionResultColumns[barcodeColumn].getCodewords()[codewordsRow];
if (codeword != null) {
invalidRowCounts = DetectionResult.adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword);
@@ -237,7 +237,7 @@ export default /*final*/ class DetectionResult {
/**
* @return true, if row number was adjusted, false otherwise
- */
+ */
private static adjustRowNumber(codeword: Codeword, otherCodeword: Codeword): boolean {
if (otherCodeword == null) {
return false;
@@ -286,9 +286,9 @@ export default /*final*/ class DetectionResult {
// try (
let formatter: Formatter = new Formatter();
// ) {
- for (let codewordsRow /*int*/ = 0; codewordsRow < rowIndicatorColumn.getCodewords().length; codewordsRow++) {
+ for (let codewordsRow /* int */ = 0; codewordsRow < rowIndicatorColumn.getCodewords().length; codewordsRow++) {
formatter.format('CW %3d:', codewordsRow);
- for (let barcodeColumn /*int*/ = 0; barcodeColumn < this.barcodeColumnCount + 2; barcodeColumn++) {
+ for (let barcodeColumn /* int */ = 0; barcodeColumn < this.barcodeColumnCount + 2; barcodeColumn++) {
if (this.detectionResultColumns[barcodeColumn] == null) {
formatter.format(' | ');
continue;
diff --git a/src/core/pdf417/decoder/DetectionResultColumn.ts b/src/core/pdf417/decoder/DetectionResultColumn.ts
index 17b5f8b4..5ba63080 100644
--- a/src/core/pdf417/decoder/DetectionResultColumn.ts
+++ b/src/core/pdf417/decoder/DetectionResultColumn.ts
@@ -29,74 +29,74 @@ import { int } from '../../../customTypings';
*/
export default class DetectionResultColumn {
- private static /*final*/ MAX_NEARBY_DISTANCE: int = 5;
+ private static /* final */ MAX_NEARBY_DISTANCE: int = 5;
- private /*final*/ boundingBox: BoundingBox;
- private /*final*/ codewords: Codeword[];
+ private /* final */ boundingBox: BoundingBox;
+ private /* final */ codewords: Codeword[];
- constructor(boundingBox: BoundingBox) {
- this.boundingBox = new BoundingBox(boundingBox);
- // this.codewords = new Codeword[boundingBox.getMaxY() - boundingBox.getMinY() + 1];
- this.codewords = new Array(boundingBox.getMaxY() - boundingBox.getMinY() + 1);
- }
+ constructor(boundingBox: BoundingBox) {
+ this.boundingBox = new BoundingBox(boundingBox);
+ // this.codewords = new Codeword[boundingBox.getMaxY() - boundingBox.getMinY() + 1];
+ this.codewords = new Array(boundingBox.getMaxY() - boundingBox.getMinY() + 1);
+ }
- /*final*/ getCodewordNearby(imageRow: int): Codeword {
- let codeword = this.getCodeword(imageRow);
+ /* final */ getCodewordNearby(imageRow: int): Codeword {
+ let codeword = this.getCodeword(imageRow);
+ if (codeword != null) {
+ return codeword;
+ }
+ for (let i = 1; i < DetectionResultColumn.MAX_NEARBY_DISTANCE; i++) {
+ let nearImageRow = this.imageRowToCodewordIndex(imageRow) - i;
+ if (nearImageRow >= 0) {
+ codeword = this.codewords[nearImageRow];
if (codeword != null) {
- return codeword;
+ return codeword;
}
- for (let i = 1; i < DetectionResultColumn.MAX_NEARBY_DISTANCE; i++) {
- let nearImageRow = this.imageRowToCodewordIndex(imageRow) - i;
- if (nearImageRow >= 0) {
- codeword = this.codewords[nearImageRow];
- if (codeword != null) {
- return codeword;
- }
- }
- nearImageRow = this.imageRowToCodewordIndex(imageRow) + i;
- if (nearImageRow < this.codewords.length) {
- codeword = this.codewords[nearImageRow];
- if (codeword != null) {
- return codeword;
- }
- }
+ }
+ nearImageRow = this.imageRowToCodewordIndex(imageRow) + i;
+ if (nearImageRow < this.codewords.length) {
+ codeword = this.codewords[nearImageRow];
+ if (codeword != null) {
+ return codeword;
}
- return null;
- }
-
- /*final int*/ imageRowToCodewordIndex(imageRow: int): int {
- return imageRow - this.boundingBox.getMinY();
- }
-
- /*final void*/ setCodeword(imageRow: int, codeword: Codeword): void {
- this.codewords[this.imageRowToCodewordIndex(imageRow)] = codeword;
+ }
}
-
-/*final*/ getCodeword(imageRow: int): Codeword {
- return this.codewords[this.imageRowToCodewordIndex(imageRow)];
+ return null;
+ }
+
+ /* final int */ imageRowToCodewordIndex(imageRow: int): int {
+ return imageRow - this.boundingBox.getMinY();
+ }
+
+ /* final void */ setCodeword(imageRow: int, codeword: Codeword): void {
+ this.codewords[this.imageRowToCodewordIndex(imageRow)] = codeword;
+ }
+
+ /* final */ getCodeword(imageRow: int): Codeword {
+ return this.codewords[this.imageRowToCodewordIndex(imageRow)];
+ }
+
+ /* final */ getBoundingBox(): BoundingBox {
+ return this.boundingBox;
+ }
+
+ /* final */ getCodewords(): Codeword[] {
+ return this.codewords;
+ }
+
+ // @Override
+ public toString(): string {
+ const formatter = new Formatter();
+ let row = 0;
+ for (const codeword of this.codewords) {
+ if (codeword == null) {
+ formatter.format('%3d: | %n', row++);
+ continue;
+ }
+ formatter.format('%3d: %3d|%3d%n', row++, codeword.getRowNumber(), codeword.getValue());
}
+ return formatter.toString();
-/*final*/ getBoundingBox(): BoundingBox {
- return this.boundingBox;
- }
-
-/*final*/ getCodewords(): Codeword[] {
- return this.codewords;
- }
-
- // @Override
- public toString(): string {
- const formatter = new Formatter();
- let row = 0;
- for (const codeword of this.codewords) {
- if (codeword == null) {
- formatter.format('%3d: | %n', row++);
- continue;
- }
- formatter.format('%3d: %3d|%3d%n', row++, codeword.getRowNumber(), codeword.getValue());
- }
- return formatter.toString();
-
- }
+ }
}
diff --git a/src/core/pdf417/decoder/DetectionResultRowIndicatorColumn.ts b/src/core/pdf417/decoder/DetectionResultRowIndicatorColumn.ts
index e7202bd8..cbd39dbd 100644
--- a/src/core/pdf417/decoder/DetectionResultRowIndicatorColumn.ts
+++ b/src/core/pdf417/decoder/DetectionResultRowIndicatorColumn.ts
@@ -32,17 +32,17 @@ import { int } from '../../../customTypings';
/**
* @author Guenther Grau
*/
-export default /*final*/ class DetectionResultRowIndicatorColumn extends DetectionResultColumn {
+export default /* final */ class DetectionResultRowIndicatorColumn extends DetectionResultColumn {
- private /*final*/ _isLeft: boolean;
+ public readonly isLeft: boolean;
constructor(boundingBox: BoundingBox, isLeft: boolean) {
super(boundingBox);
- this._isLeft = isLeft;
+ this.isLeft = isLeft;
}
private setRowNumbers(): void {
- for (let codeword /*Codeword*/ of this.getCodewords()) {
+ for (let codeword /* Codeword */ of this.getCodewords()) {
if (codeword != null) {
codeword.setRowNumberAsRowIndicatorColumn();
}
@@ -58,17 +58,17 @@ export default /*final*/ class DetectionResultRowIndicatorColumn extends Detecti
this.setRowNumbers();
this.removeIncorrectCodewords(codewords, barcodeMetadata);
let boundingBox: BoundingBox = this.getBoundingBox();
- let top: ResultPoint = this._isLeft ? boundingBox.getTopLeft() : boundingBox.getTopRight();
- let bottom: ResultPoint = this._isLeft ? boundingBox.getBottomLeft() : boundingBox.getBottomRight();
- let firstRow: int = this.imageRowToCodewordIndex( Math.trunc(top.getY()));
- let lastRow: int = this.imageRowToCodewordIndex( Math.trunc(bottom.getY()));
+ let top: ResultPoint = this.isLeft ? boundingBox.getTopLeft() : boundingBox.getTopRight();
+ let bottom: ResultPoint = this.isLeft ? boundingBox.getBottomLeft() : boundingBox.getBottomRight();
+ let firstRow: int = this.imageRowToCodewordIndex(Math.trunc(top.getY()));
+ let lastRow: int = this.imageRowToCodewordIndex(Math.trunc(bottom.getY()));
// We need to be careful using the average row height. Barcode could be skewed so that we have smaller and
// taller rows
- // float averageRowHeight = (lastRow - firstRow) / /*(float)*/ barcodeMetadata.getRowCount();
+ // float averageRowHeight = (lastRow - firstRow) / /*(float) */ barcodeMetadata.getRowCount();
let barcodeRow: int = -1;
let maxRowHeight: int = 1;
let currentRowHeight: int = 0;
- for (let codewordsRow /*int*/ = firstRow; codewordsRow < lastRow; codewordsRow++) {
+ for (let codewordsRow /* int */ = firstRow; codewordsRow < lastRow; codewordsRow++) {
if (codewords[codewordsRow] == null) {
continue;
}
@@ -93,8 +93,8 @@ export default /*final*/ class DetectionResultRowIndicatorColumn extends Detecti
currentRowHeight = 1;
barcodeRow = codeword.getRowNumber();
} else if (rowDifference < 0 ||
- codeword.getRowNumber() >= barcodeMetadata.getRowCount() ||
- rowDifference > codewordsRow) {
+ codeword.getRowNumber() >= barcodeMetadata.getRowCount() ||
+ rowDifference > codewordsRow) {
codewords[codewordsRow] = null;
} else {
let checkedRows: int;
@@ -104,7 +104,7 @@ export default /*final*/ class DetectionResultRowIndicatorColumn extends Detecti
checkedRows = rowDifference;
}
let closePreviousCodewordFound: boolean = checkedRows >= codewordsRow;
- for (let i /*int*/ = 1; i <= checkedRows && !closePreviousCodewordFound; i++) {
+ for (let i /* int */ = 1; i <= checkedRows && !closePreviousCodewordFound; i++) {
// there must be (height * rowDifference) number of codewords missing. For now we assume height = 1.
// This should hopefully get rid of most problems already.
closePreviousCodewordFound = codewords[codewordsRow - i] != null;
@@ -127,7 +127,7 @@ export default /*final*/ class DetectionResultRowIndicatorColumn extends Detecti
}
this.adjustIncompleteIndicatorColumnRowNumbers(barcodeMetadata);
let result: Int32Array = new Int32Array(barcodeMetadata.getRowCount());
- for (let codeword /*Codeword*/ of this.getCodewords()) {
+ for (let codeword /* Codeword */ of this.getCodewords()) {
if (codeword != null) {
let rowNumber: int = codeword.getRowNumber();
if (rowNumber >= result.length) {
@@ -145,16 +145,16 @@ export default /*final*/ class DetectionResultRowIndicatorColumn extends Detecti
// use row height count to make detection of invalid row numbers more reliable
private adjustIncompleteIndicatorColumnRowNumbers(barcodeMetadata: BarcodeMetadata): void {
let boundingBox: BoundingBox = this.getBoundingBox();
- let top: ResultPoint = this._isLeft ? boundingBox.getTopLeft() : boundingBox.getTopRight();
- let bottom: ResultPoint = this._isLeft ? boundingBox.getBottomLeft() : boundingBox.getBottomRight();
- let firstRow: int = this.imageRowToCodewordIndex( Math.trunc(top.getY()));
- let lastRow: int = this.imageRowToCodewordIndex( Math.trunc(bottom.getY()));
- // float averageRowHeight = (lastRow - firstRow) / /*(float)*/ barcodeMetadata.getRowCount();
+ let top: ResultPoint = this.isLeft ? boundingBox.getTopLeft() : boundingBox.getTopRight();
+ let bottom: ResultPoint = this.isLeft ? boundingBox.getBottomLeft() : boundingBox.getBottomRight();
+ let firstRow: int = this.imageRowToCodewordIndex(Math.trunc(top.getY()));
+ let lastRow: int = this.imageRowToCodewordIndex(Math.trunc(bottom.getY()));
+ // float averageRowHeight = (lastRow - firstRow) / /*(float) */ barcodeMetadata.getRowCount();
let codewords: Codeword[] = this.getCodewords();
let barcodeRow: int = -1;
let maxRowHeight: int = 1;
let currentRowHeight: int = 0;
- for (let codewordsRow /*int*/ = firstRow; codewordsRow < lastRow; codewordsRow++) {
+ for (let codewordsRow /* int */ = firstRow; codewordsRow < lastRow; codewordsRow++) {
if (codewords[codewordsRow] == null) {
continue;
}
@@ -188,14 +188,14 @@ export default /*final*/ class DetectionResultRowIndicatorColumn extends Detecti
let barcodeRowCountUpperPart: BarcodeValue = new BarcodeValue();
let barcodeRowCountLowerPart: BarcodeValue = new BarcodeValue();
let barcodeECLevel: BarcodeValue = new BarcodeValue();
- for (let codeword /*Codeword*/ of codewords) {
+ for (let codeword /* Codeword */ of codewords) {
if (codeword == null) {
continue;
}
codeword.setRowNumberAsRowIndicatorColumn();
let rowIndicatorValue: int = codeword.getValue() % 30;
let codewordRowNumber: int = codeword.getRowNumber();
- if (!this._isLeft) {
+ if (!this.isLeft) {
codewordRowNumber += 2;
}
switch (codewordRowNumber % 3) {
@@ -213,16 +213,16 @@ export default /*final*/ class DetectionResultRowIndicatorColumn extends Detecti
}
// Maybe we should check if we have ambiguous values?
if ((barcodeColumnCount.getValue().length === 0) ||
- (barcodeRowCountUpperPart.getValue().length === 0) ||
- (barcodeRowCountLowerPart.getValue().length === 0) ||
- (barcodeECLevel.getValue().length === 0) ||
- barcodeColumnCount.getValue()[0] < 1 ||
- barcodeRowCountUpperPart.getValue()[0] + barcodeRowCountLowerPart.getValue()[0] < PDF417Common.MIN_ROWS_IN_BARCODE ||
- barcodeRowCountUpperPart.getValue()[0] + barcodeRowCountLowerPart.getValue()[0] > PDF417Common.MAX_ROWS_IN_BARCODE) {
+ (barcodeRowCountUpperPart.getValue().length === 0) ||
+ (barcodeRowCountLowerPart.getValue().length === 0) ||
+ (barcodeECLevel.getValue().length === 0) ||
+ barcodeColumnCount.getValue()[0] < 1 ||
+ barcodeRowCountUpperPart.getValue()[0] + barcodeRowCountLowerPart.getValue()[0] < PDF417Common.MIN_ROWS_IN_BARCODE ||
+ barcodeRowCountUpperPart.getValue()[0] + barcodeRowCountLowerPart.getValue()[0] > PDF417Common.MAX_ROWS_IN_BARCODE) {
return null;
}
let barcodeMetadata: BarcodeMetadata = new BarcodeMetadata(barcodeColumnCount.getValue()[0],
- barcodeRowCountUpperPart.getValue()[0], barcodeRowCountLowerPart.getValue()[0], barcodeECLevel.getValue()[0]);
+ barcodeRowCountUpperPart.getValue()[0], barcodeRowCountLowerPart.getValue()[0], barcodeECLevel.getValue()[0]);
this.removeIncorrectCodewords(codewords, barcodeMetadata);
return barcodeMetadata;
}
@@ -230,7 +230,7 @@ export default /*final*/ class DetectionResultRowIndicatorColumn extends Detecti
private removeIncorrectCodewords(codewords: Codeword[], barcodeMetadata: BarcodeMetadata): void {
// Remove codewords which do not match the metadata
// TODO Maybe we should keep the incorrect codewords for the start and end positions?
- for (let codewordRow /*int*/ = 0; codewordRow < codewords.length; codewordRow++) {
+ for (let codewordRow /* int */ = 0; codewordRow < codewords.length; codewordRow++) {
let codeword: Codeword = codewords[codewordRow];
if (codewords[codewordRow] == null) {
continue;
@@ -241,7 +241,7 @@ export default /*final*/ class DetectionResultRowIndicatorColumn extends Detecti
codewords[codewordRow] = null;
continue;
}
- if (!this._isLeft) {
+ if (!this.isLeft) {
codewordRowNumber += 2;
}
switch (codewordRowNumber % 3) {
@@ -252,7 +252,7 @@ export default /*final*/ class DetectionResultRowIndicatorColumn extends Detecti
break;
case 1:
if (Math.trunc(rowIndicatorValue / 3) !== barcodeMetadata.getErrorCorrectionLevel() ||
- rowIndicatorValue % 3 !== barcodeMetadata.getRowCountLowerPart()) {
+ rowIndicatorValue % 3 !== barcodeMetadata.getRowCountLowerPart()) {
codewords[codewordRow] = null;
}
break;
@@ -265,13 +265,9 @@ export default /*final*/ class DetectionResultRowIndicatorColumn extends Detecti
}
}
- isLeft(): boolean {
- return this._isLeft;
- }
-
// @Override
public toString(): string {
- return 'IsLeft: ' + this._isLeft + '\n' + super.toString();
+ return 'IsLeft: ' + this.isLeft + '\n' + super.toString();
}
}
diff --git a/src/core/pdf417/decoder/PDF417CodewordDecoder.ts b/src/core/pdf417/decoder/PDF417CodewordDecoder.ts
index 4710a1d6..215ac8af 100644
--- a/src/core/pdf417/decoder/PDF417CodewordDecoder.ts
+++ b/src/core/pdf417/decoder/PDF417CodewordDecoder.ts
@@ -28,25 +28,25 @@ import { int, float } from '../../../customTypings';
* @author Guenther Grau
* @author creatale GmbH (christoph.schulz@creatale.de)
*/
-export default /*final*/ class PDF417CodewordDecoder {
+export default /* final */ class PDF417CodewordDecoder {
// flag that the table is ready for use
private static bSymbolTableReady: boolean = false;
- private static /*final float[][]*/ RATIOS_TABLE: number[][] =
- new Array(PDF417Common.SYMBOL_TABLE.length).map(x => x = new Array(PDF417Common.BARS_IN_MODULE));
+ private static /* final float[][] */ RATIOS_TABLE: number[][] =
+ new Array(PDF417Common.SYMBOL_TABLE.length).map(x => x = new Array(PDF417Common.BARS_IN_MODULE));
/* @note
* this action have to be performed before first use of class
* - static constructor
* working with 32bit float (based from Java logic)
- */
+ */
static initialize() {
- // Pre-computes the symbol ratio table.
- for (/*int*/let i = 0; i < PDF417Common.SYMBOL_TABLE.length; i++) {
+ // Pre-computes the symbol ratio table.
+ for (/* int */let i = 0; i < PDF417Common.SYMBOL_TABLE.length; i++) {
let currentSymbol: int = PDF417Common.SYMBOL_TABLE[i];
let currentBit: int = currentSymbol & 0x1;
- for (/*int*/ let j = 0; j < PDF417Common.BARS_IN_MODULE; j++) {
+ for (/* int */ let j = 0; j < PDF417Common.BARS_IN_MODULE; j++) {
let size: float = 0.0;
while ((currentSymbol & 0x1) === currentBit) {
size += 1.0;
@@ -63,10 +63,10 @@ export default /*final*/ class PDF417CodewordDecoder {
}
static getDecodedValue(moduleBitCount: Int32Array): int {
- let decodedValue: int = PDF417CodewordDecoder.getDecodedCodewordValue(PDF417CodewordDecoder.sampleBitCounts(moduleBitCount));
- if (decodedValue !== -1) {
+ let decodedValue: int = PDF417CodewordDecoder.getDecodedCodewordValue(PDF417CodewordDecoder.sampleBitCounts(moduleBitCount));
+ if (decodedValue !== -1) {
return decodedValue;
- }
+ }
return PDF417CodewordDecoder.getClosestDecodedValue(moduleBitCount);
}
@@ -75,10 +75,10 @@ export default /*final*/ class PDF417CodewordDecoder {
let result: Int32Array = new Int32Array(PDF417Common.BARS_IN_MODULE);
let bitCountIndex: int = 0;
let sumPreviousBits: int = 0;
- for (/*int*/ let i = 0; i < PDF417Common.MODULES_IN_CODEWORD; i++) {
+ for (/* int */ let i = 0; i < PDF417Common.MODULES_IN_CODEWORD; i++) {
let sampleIndex: float =
- bitCountSum / (2 * PDF417Common.MODULES_IN_CODEWORD) +
- (i * bitCountSum) / PDF417Common.MODULES_IN_CODEWORD;
+ bitCountSum / (2 * PDF417Common.MODULES_IN_CODEWORD) +
+ (i * bitCountSum) / PDF417Common.MODULES_IN_CODEWORD;
if (sumPreviousBits + moduleBitCount[bitCountIndex] <= sampleIndex) {
sumPreviousBits += moduleBitCount[bitCountIndex];
bitCountIndex++;
@@ -94,13 +94,13 @@ export default /*final*/ class PDF417CodewordDecoder {
}
private static getBitValue(moduleBitCount: Int32Array): int {
- let result: /*long*/ number = 0;
- for (let /*int*/ i = 0; i < moduleBitCount.length; i++) {
- for (/*int*/ let bit = 0; bit < moduleBitCount[i]; bit++) {
+ let result: /* long */ number = 0;
+ for (let /* int */ i = 0; i < moduleBitCount.length; i++) {
+ for (/* int */ let bit = 0; bit < moduleBitCount[i]; bit++) {
result = (result << 1) | (i % 2 === 0 ? 1 : 0);
}
}
- return Math.trunc(result);
+ return Math.trunc(result);
}
// working with 32bit float (as in Java)
@@ -108,7 +108,7 @@ export default /*final*/ class PDF417CodewordDecoder {
let bitCountSum: int = MathUtils.sum(moduleBitCount);
let bitCountRatios: float[] = new Array(PDF417Common.BARS_IN_MODULE);
if (bitCountSum > 1) {
- for (let /*int*/ i = 0; i < bitCountRatios.length; i++) {
+ for (let /* int */ i = 0; i < bitCountRatios.length; i++) {
bitCountRatios[i] = Math.fround(moduleBitCount[i] / bitCountSum);
}
}
@@ -117,10 +117,10 @@ export default /*final*/ class PDF417CodewordDecoder {
if (!this.bSymbolTableReady) {
PDF417CodewordDecoder.initialize();
}
- for (/*int*/ let j = 0; j < PDF417CodewordDecoder.RATIOS_TABLE.length; j++) {
+ for (/* int */ let j = 0; j < PDF417CodewordDecoder.RATIOS_TABLE.length; j++) {
let error: float = 0.0;
let ratioTableRow: float[] = PDF417CodewordDecoder.RATIOS_TABLE[j];
- for (/*int*/ let k = 0; k < PDF417Common.BARS_IN_MODULE; k++) {
+ for (/* int */ let k = 0; k < PDF417Common.BARS_IN_MODULE; k++) {
let diff: float = Math.fround(ratioTableRow[k] - bitCountRatios[k]);
error += Math.fround(diff * diff);
if (error >= bestMatchError) {
diff --git a/src/core/pdf417/decoder/PDF417ScanningDecoder.ts b/src/core/pdf417/decoder/PDF417ScanningDecoder.ts
index e9062e5d..096e65b3 100644
--- a/src/core/pdf417/decoder/PDF417ScanningDecoder.ts
+++ b/src/core/pdf417/decoder/PDF417ScanningDecoder.ts
@@ -58,15 +58,15 @@ import { int, List, Collection } from '../../../customTypings';
/**
* @author Guenther Grau
*/
-export default /*public final*/ class PDF417ScanningDecoder {
+export default /* public final */ class PDF417ScanningDecoder {
- /*final*/ static CODEWORD_SKEW_SIZE: int = 2;
+ /* final */ static CODEWORD_SKEW_SIZE: int = 2;
- /*final*/ static MAX_ERRORS: int = 3;
- /*final*/ static MAX_EC_CODEWORDS: int = 512;
- /*final*/ static errorCorrection: ErrorCorrection = new ErrorCorrection();
+ /* final */ static MAX_ERRORS: int = 3;
+ /* final */ static MAX_EC_CODEWORDS: int = 512;
+ /* final */ static errorCorrection: ErrorCorrection = new ErrorCorrection();
- private constructor() {}
+ private constructor() { }
/**
* @TODO don't pass in minCodewordWidth and maxCodewordWidth, pass in barcode columns for start and stop pattern
@@ -93,7 +93,7 @@ export default /*public final*/ class PDF417ScanningDecoder {
* @throws NotFoundException
* @throws FormatException
* @throws ChecksumException
- */
+ */
public static decode(image: BitMatrix,
imageTopLeft: ResultPoint,
imageBottomLeft: ResultPoint,
@@ -105,7 +105,7 @@ export default /*public final*/ class PDF417ScanningDecoder {
let leftRowIndicatorColumn: DetectionResultRowIndicatorColumn = null;
let rightRowIndicatorColumn: DetectionResultRowIndicatorColumn = null;
let detectionResult: DetectionResult;
- for (let firstPass /*boolean*/ = true; ; firstPass = false) {
+ for (let firstPass /* boolean */ = true; ; firstPass = false) {
if (imageTopLeft != null) {
leftRowIndicatorColumn = PDF417ScanningDecoder.getRowIndicatorColumn(image, boundingBox, imageTopLeft, true, minCodewordWidth,
maxCodewordWidth);
@@ -132,7 +132,7 @@ export default /*public final*/ class PDF417ScanningDecoder {
detectionResult.setDetectionResultColumn(maxBarcodeColumn, rightRowIndicatorColumn);
let leftToRight: boolean = leftRowIndicatorColumn != null;
- for (let barcodeColumnCount /*int*/ = 1; barcodeColumnCount <= maxBarcodeColumn; barcodeColumnCount++) {
+ for (let barcodeColumnCount /* int */ = 1; barcodeColumnCount <= maxBarcodeColumn; barcodeColumnCount++) {
let barcodeColumn: int = leftToRight ? barcodeColumnCount : maxBarcodeColumn - barcodeColumnCount;
if (detectionResult.getDetectionResultColumn(barcodeColumn) !== /* null */ undefined) {
// This will be the case for the opposite row indicator column, which doesn't need to be decoded again.
@@ -148,7 +148,7 @@ export default /*public final*/ class PDF417ScanningDecoder {
let startColumn: int = -1;
let previousStartColumn: int = startColumn;
// TODO start at a row for which we know the start position, then detect upwards and downwards from there.
- for (let imageRow /*int*/ = boundingBox.getMinY(); imageRow <= boundingBox.getMaxY(); imageRow++) {
+ for (let imageRow /* int */ = boundingBox.getMinY(); imageRow <= boundingBox.getMaxY(); imageRow++) {
startColumn = PDF417ScanningDecoder.getStartColumn(detectionResult, barcodeColumn, imageRow, leftToRight);
if (startColumn < 0 || startColumn > boundingBox.getMaxX()) {
if (previousStartColumn === -1) {
@@ -175,7 +175,7 @@ export default /*public final*/ class PDF417ScanningDecoder {
* @param rightRowIndicatorColumn
*
* @throws NotFoundException
- */
+ */
private static merge(leftRowIndicatorColumn: DetectionResultRowIndicatorColumn,
rightRowIndicatorColumn: DetectionResultRowIndicatorColumn): DetectionResult {
if (leftRowIndicatorColumn == null && rightRowIndicatorColumn == null) {
@@ -195,7 +195,7 @@ export default /*public final*/ class PDF417ScanningDecoder {
* @param rowIndicatorColumn
*
* @throws NotFoundException
- */
+ */
private static adjustBoundingBox(rowIndicatorColumn: DetectionResultRowIndicatorColumn): BoundingBox {
if (rowIndicatorColumn == null) {
return null;
@@ -206,33 +206,33 @@ export default /*public final*/ class PDF417ScanningDecoder {
}
let maxRowHeight: int = PDF417ScanningDecoder.getMax(rowHeights);
let missingStartRows: int = 0;
- for (let rowHeight /*int*/ of rowHeights) {
+ for (let rowHeight /* int */ of rowHeights) {
missingStartRows += maxRowHeight - rowHeight;
if (rowHeight > 0) {
break;
}
}
let codewords: Codeword[] = rowIndicatorColumn.getCodewords();
- for (let row /*int*/ = 0; missingStartRows > 0 && codewords[row] == null; row++) {
+ for (let row /* int */ = 0; missingStartRows > 0 && codewords[row] == null; row++) {
missingStartRows--;
}
let missingEndRows: int = 0;
- for (let row /*int*/ = rowHeights.length - 1; row >= 0; row--) {
+ for (let row /* int */ = rowHeights.length - 1; row >= 0; row--) {
missingEndRows += maxRowHeight - rowHeights[row];
if (rowHeights[row] > 0) {
break;
}
}
- for (let row /*int*/ = codewords.length - 1; missingEndRows > 0 && codewords[row] == null; row--) {
+ for (let row /* int */ = codewords.length - 1; missingEndRows > 0 && codewords[row] == null; row--) {
missingEndRows--;
}
return rowIndicatorColumn.getBoundingBox().addMissingRows(missingStartRows, missingEndRows,
- rowIndicatorColumn.isLeft());
+ rowIndicatorColumn.isLeft);
}
private static getMax(values: Int32Array): int {
let maxValue: int = -1;
- for (let value /*int*/ of values) {
+ for (let value /* int */ of values) {
maxValue = Math.max(maxValue, value);
}
return maxValue;
@@ -267,10 +267,10 @@ export default /*public final*/ class PDF417ScanningDecoder {
maxCodewordWidth: int): DetectionResultRowIndicatorColumn {
let rowIndicatorColumn: DetectionResultRowIndicatorColumn = new DetectionResultRowIndicatorColumn(boundingBox,
leftToRight);
- for (let i /*int*/ = 0; i < 2; i++) {
+ for (let i /* int */ = 0; i < 2; i++) {
let increment: int = i === 0 ? 1 : -1;
let startColumn: int = Math.trunc(Math.trunc(startPoint.getX()));
- for (let imageRow /*int*/ = Math.trunc(Math.trunc(startPoint.getY())); imageRow <= boundingBox.getMaxY() &&
+ for (let imageRow /* int */ = Math.trunc(Math.trunc(startPoint.getY())); imageRow <= boundingBox.getMaxY() &&
imageRow >= boundingBox.getMinY(); imageRow += increment) {
let codeword: Codeword = PDF417ScanningDecoder.detectCodeword(image, 0, image.getWidth(), leftToRight, startColumn, imageRow,
minCodewordWidth, maxCodewordWidth);
@@ -296,7 +296,7 @@ export default /*public final*/ class PDF417ScanningDecoder {
* @param barcodeMatrix
*
* @throws NotFoundException
- */
+ */
private static adjustCodewordCount(detectionResult: DetectionResult, barcodeMatrix: BarcodeValue[][]): void {
let barcodeMatrix01: BarcodeValue = barcodeMatrix[0][1];
let numberOfCodewords: Int32Array = barcodeMatrix01.getValue();
@@ -321,16 +321,16 @@ export default /*public final*/ class PDF417ScanningDecoder {
* @throws FormatException
* @throws ChecksumException
* @throws NotFoundException
- */
+ */
private static createDecoderResult(detectionResult: DetectionResult): DecoderResult {
let barcodeMatrix: BarcodeValue[][] = PDF417ScanningDecoder.createBarcodeMatrix(detectionResult);
PDF417ScanningDecoder.adjustCodewordCount(detectionResult, barcodeMatrix);
- let erasures /*Collection*/ = new Array();
+ let erasures /* Collection */ = new Array();
let codewords: Int32Array = new Int32Array(detectionResult.getBarcodeRowCount() * detectionResult.getBarcodeColumnCount());
- let ambiguousIndexValuesList: /*List