UNPKG

@zxing/library

Version:

TypeScript port of ZXing multi-format 1D/2D barcode image processing library.

298 lines (297 loc) 14.4 kB
"use strict"; /* * Copyright 2013 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. */ var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; Object.defineProperty(exports, "__esModule", { value: true }); // package com.google.zxing.pdf417.decoder; // import com.google.zxing.pdf417.PDF417Common; var PDF417Common_1 = require("../PDF417Common"); var Formatter_1 = require("../../util/Formatter"); /** * @author Guenther Grau */ var DetectionResult = /** @class */ (function () { function DetectionResult(barcodeMetadata, boundingBox) { /*final*/ this.ADJUST_ROW_NUMBER_SKIP = 2; this.barcodeMetadata = barcodeMetadata; this.barcodeColumnCount = barcodeMetadata.getColumnCount(); this.boundingBox = boundingBox; // this.detectionResultColumns = new DetectionResultColumn[this.barcodeColumnCount + 2]; this.detectionResultColumns = new Array(this.barcodeColumnCount + 2); } DetectionResult.prototype.getDetectionResultColumns = function () { this.adjustIndicatorColumnRowNumbers(this.detectionResultColumns[0]); this.adjustIndicatorColumnRowNumbers(this.detectionResultColumns[this.barcodeColumnCount + 1]); var unadjustedCodewordCount = PDF417Common_1.default.MAX_CODEWORDS_IN_BARCODE; var previousUnadjustedCount; do { previousUnadjustedCount = unadjustedCodewordCount; unadjustedCodewordCount = this.adjustRowNumbersAndGetCount(); } while (unadjustedCodewordCount > 0 && unadjustedCodewordCount < previousUnadjustedCount); return this.detectionResultColumns; }; DetectionResult.prototype.adjustIndicatorColumnRowNumbers = function (detectionResultColumn) { if (detectionResultColumn != null) { detectionResultColumn .adjustCompleteIndicatorColumnRowNumbers(this.barcodeMetadata); } }; // TODO ensure that no detected codewords with unknown row number are left // we should be able to estimate the row height and use it as a hint for the row number // we should also fill the rows top to bottom and bottom to top /** * @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 */ DetectionResult.prototype.adjustRowNumbersAndGetCount = function () { var unadjustedCount = this.adjustRowNumbersByRow(); if (unadjustedCount === 0) { return 0; } for (var barcodeColumn /*int*/ = 1; barcodeColumn < this.barcodeColumnCount + 1; barcodeColumn++) { var codewords = this.detectionResultColumns[barcodeColumn].getCodewords(); for (var codewordsRow /*int*/ = 0; codewordsRow < codewords.length; codewordsRow++) { if (codewords[codewordsRow] == null) { continue; } if (!codewords[codewordsRow].hasValidRowNumber()) { this.adjustRowNumbers(barcodeColumn, codewordsRow, codewords); } } } return unadjustedCount; }; DetectionResult.prototype.adjustRowNumbersByRow = function () { this.adjustRowNumbersFromBothRI(); // TODO we should only do full row adjustments if row numbers of left and right row indicator column match. // Maybe it's even better to calculated the height (rows: d) and divide it by the number of barcode // rows. This, together with the LRI and RRI row numbers should allow us to get a good estimate where a row // number starts and ends. var unadjustedCount = this.adjustRowNumbersFromLRI(); return unadjustedCount + this.adjustRowNumbersFromRRI(); }; DetectionResult.prototype.adjustRowNumbersFromBothRI = function () { if (this.detectionResultColumns[0] == null || this.detectionResultColumns[this.barcodeColumnCount + 1] == null) { return; } var LRIcodewords = this.detectionResultColumns[0].getCodewords(); var RRIcodewords = this.detectionResultColumns[this.barcodeColumnCount + 1].getCodewords(); for (var codewordsRow /*int*/ = 0; codewordsRow < LRIcodewords.length; codewordsRow++) { if (LRIcodewords[codewordsRow] != null && RRIcodewords[codewordsRow] != null && LRIcodewords[codewordsRow].getRowNumber() === RRIcodewords[codewordsRow].getRowNumber()) { for (var barcodeColumn /*int*/ = 1; barcodeColumn <= this.barcodeColumnCount; barcodeColumn++) { var codeword = this.detectionResultColumns[barcodeColumn].getCodewords()[codewordsRow]; if (codeword == null) { continue; } codeword.setRowNumber(LRIcodewords[codewordsRow].getRowNumber()); if (!codeword.hasValidRowNumber()) { this.detectionResultColumns[barcodeColumn].getCodewords()[codewordsRow] = null; } } } } }; DetectionResult.prototype.adjustRowNumbersFromRRI = function () { if (this.detectionResultColumns[this.barcodeColumnCount + 1] == null) { return 0; } var unadjustedCount = 0; var codewords = this.detectionResultColumns[this.barcodeColumnCount + 1].getCodewords(); for (var codewordsRow /*int*/ = 0; codewordsRow < codewords.length; codewordsRow++) { if (codewords[codewordsRow] == null) { continue; } var rowIndicatorRowNumber = codewords[codewordsRow].getRowNumber(); var invalidRowCounts = 0; for (var barcodeColumn /*int*/ = this.barcodeColumnCount + 1; barcodeColumn > 0 && invalidRowCounts < this.ADJUST_ROW_NUMBER_SKIP; barcodeColumn--) { var codeword = this.detectionResultColumns[barcodeColumn].getCodewords()[codewordsRow]; if (codeword != null) { invalidRowCounts = DetectionResult.adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword); if (!codeword.hasValidRowNumber()) { unadjustedCount++; } } } } return unadjustedCount; }; DetectionResult.prototype.adjustRowNumbersFromLRI = function () { if (this.detectionResultColumns[0] == null) { return 0; } var unadjustedCount = 0; var codewords = this.detectionResultColumns[0].getCodewords(); for (var codewordsRow /*int*/ = 0; codewordsRow < codewords.length; codewordsRow++) { if (codewords[codewordsRow] == null) { continue; } var rowIndicatorRowNumber = codewords[codewordsRow].getRowNumber(); var invalidRowCounts = 0; for (var barcodeColumn /*int*/ = 1; barcodeColumn < this.barcodeColumnCount + 1 && invalidRowCounts < this.ADJUST_ROW_NUMBER_SKIP; barcodeColumn++) { var codeword = this.detectionResultColumns[barcodeColumn].getCodewords()[codewordsRow]; if (codeword != null) { invalidRowCounts = DetectionResult.adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword); if (!codeword.hasValidRowNumber()) { unadjustedCount++; } } } } return unadjustedCount; }; DetectionResult.adjustRowNumberIfValid = function (rowIndicatorRowNumber, invalidRowCounts, codeword) { if (codeword == null) { return invalidRowCounts; } if (!codeword.hasValidRowNumber()) { if (codeword.isValidRowNumber(rowIndicatorRowNumber)) { codeword.setRowNumber(rowIndicatorRowNumber); invalidRowCounts = 0; } else { ++invalidRowCounts; } } return invalidRowCounts; }; DetectionResult.prototype.adjustRowNumbers = function (barcodeColumn, codewordsRow, codewords) { var e_1, _a; if (this.detectionResultColumns[barcodeColumn - 1] == null) { return; } var codeword = codewords[codewordsRow]; var previousColumnCodewords = this.detectionResultColumns[barcodeColumn - 1].getCodewords(); var nextColumnCodewords = previousColumnCodewords; if (this.detectionResultColumns[barcodeColumn + 1] != null) { nextColumnCodewords = this.detectionResultColumns[barcodeColumn + 1].getCodewords(); } // let otherCodewords: Codeword[] = new Codeword[14]; var otherCodewords = new Array(14); otherCodewords[2] = previousColumnCodewords[codewordsRow]; otherCodewords[3] = nextColumnCodewords[codewordsRow]; if (codewordsRow > 0) { otherCodewords[0] = codewords[codewordsRow - 1]; otherCodewords[4] = previousColumnCodewords[codewordsRow - 1]; otherCodewords[5] = nextColumnCodewords[codewordsRow - 1]; } if (codewordsRow > 1) { otherCodewords[8] = codewords[codewordsRow - 2]; otherCodewords[10] = previousColumnCodewords[codewordsRow - 2]; otherCodewords[11] = nextColumnCodewords[codewordsRow - 2]; } if (codewordsRow < codewords.length - 1) { otherCodewords[1] = codewords[codewordsRow + 1]; otherCodewords[6] = previousColumnCodewords[codewordsRow + 1]; otherCodewords[7] = nextColumnCodewords[codewordsRow + 1]; } if (codewordsRow < codewords.length - 2) { otherCodewords[9] = codewords[codewordsRow + 2]; otherCodewords[12] = previousColumnCodewords[codewordsRow + 2]; otherCodewords[13] = nextColumnCodewords[codewordsRow + 2]; } try { for (var otherCodewords_1 = __values(otherCodewords), otherCodewords_1_1 = otherCodewords_1.next(); !otherCodewords_1_1.done; otherCodewords_1_1 = otherCodewords_1.next()) { var otherCodeword = otherCodewords_1_1.value; if (DetectionResult.adjustRowNumber(codeword, otherCodeword)) { return; } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (otherCodewords_1_1 && !otherCodewords_1_1.done && (_a = otherCodewords_1.return)) _a.call(otherCodewords_1); } finally { if (e_1) throw e_1.error; } } }; /** * @return true, if row number was adjusted, false otherwise */ DetectionResult.adjustRowNumber = function (codeword, otherCodeword) { if (otherCodeword == null) { return false; } if (otherCodeword.hasValidRowNumber() && otherCodeword.getBucket() === codeword.getBucket()) { codeword.setRowNumber(otherCodeword.getRowNumber()); return true; } return false; }; DetectionResult.prototype.getBarcodeColumnCount = function () { return this.barcodeColumnCount; }; DetectionResult.prototype.getBarcodeRowCount = function () { return this.barcodeMetadata.getRowCount(); }; DetectionResult.prototype.getBarcodeECLevel = function () { return this.barcodeMetadata.getErrorCorrectionLevel(); }; DetectionResult.prototype.setBoundingBox = function (boundingBox) { this.boundingBox = boundingBox; }; DetectionResult.prototype.getBoundingBox = function () { return this.boundingBox; }; DetectionResult.prototype.setDetectionResultColumn = function (barcodeColumn, detectionResultColumn) { this.detectionResultColumns[barcodeColumn] = detectionResultColumn; }; DetectionResult.prototype.getDetectionResultColumn = function (barcodeColumn) { return this.detectionResultColumns[barcodeColumn]; }; // @Override DetectionResult.prototype.toString = function () { var rowIndicatorColumn = this.detectionResultColumns[0]; if (rowIndicatorColumn == null) { rowIndicatorColumn = this.detectionResultColumns[this.barcodeColumnCount + 1]; } // try ( var formatter = new Formatter_1.default(); // ) { for (var codewordsRow /*int*/ = 0; codewordsRow < rowIndicatorColumn.getCodewords().length; codewordsRow++) { formatter.format('CW %3d:', codewordsRow); for (var barcodeColumn /*int*/ = 0; barcodeColumn < this.barcodeColumnCount + 2; barcodeColumn++) { if (this.detectionResultColumns[barcodeColumn] == null) { formatter.format(' | '); continue; } var codeword = this.detectionResultColumns[barcodeColumn].getCodewords()[codewordsRow]; if (codeword == null) { formatter.format(' | '); continue; } formatter.format(' %3d|%3d', codeword.getRowNumber(), codeword.getValue()); } formatter.format('%n'); } return formatter.toString(); // } }; return DetectionResult; }()); exports.default = DetectionResult;