UNPKG

@zxing/library

Version:

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

124 lines (123 loc) 4.15 kB
/* * Copyright 2008 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. */ /*namespace com.google.zxing.oned {*/ import BarcodeFormat from '../BarcodeFormat'; import NotFoundException from '../NotFoundException'; import OneDReader from './OneDReader'; import Result from '../Result'; import ResultPoint from '../ResultPoint'; /** * <p>Decodes CodaBar barcodes. </p> * * @author Evan @dodobelieve * @see CodaBarReader */ export default class CodaBarReader extends OneDReader { constructor() { super(...arguments); this.CODA_BAR_CHAR_SET = { nnnnnww: '0', nnnnwwn: '1', nnnwnnw: '2', wwnnnnn: '3', nnwnnwn: '4', wnnnnwn: '5', nwnnnnw: '6', nwnnwnn: '7', nwwnnnn: '8', wnnwnnn: '9', nnnwwnn: '-', nnwwnnn: '$', wnnnwnw: ':', wnwnnnw: '/', wnwnwnn: '.', nnwwwww: '+', nnwwnwn: 'A', nwnwnnw: 'B', nnnwnww: 'C', nnnwwwn: 'D' }; } decodeRow(rowNumber, row, hints) { let validRowData = this.getValidRowData(row); if (!validRowData) throw new NotFoundException(); let retStr = this.codaBarDecodeRow(validRowData.row); if (!retStr) throw new NotFoundException(); return new Result(retStr, null, 0, [new ResultPoint(validRowData.left, rowNumber), new ResultPoint(validRowData.right, rowNumber)], BarcodeFormat.CODABAR, new Date().getTime()); } /** * converts bit array to valid data array(lengths of black bits and white bits) * @param row bit array to convert */ getValidRowData(row) { let booleanArr = row.toArray(); let startIndex = booleanArr.indexOf(true); if (startIndex === -1) return null; let lastIndex = booleanArr.lastIndexOf(true); if (lastIndex <= startIndex) return null; booleanArr = booleanArr.slice(startIndex, lastIndex + 1); let result = []; let lastBit = booleanArr[0]; let bitLength = 1; for (let i = 1; i < booleanArr.length; i++) { if (booleanArr[i] === lastBit) { bitLength++; } else { lastBit = booleanArr[i]; result.push(bitLength); bitLength = 1; } } result.push(bitLength); // CodaBar code data valid if (result.length < 23 && (result.length + 1) % 8 !== 0) return null; return { row: result, left: startIndex, right: lastIndex }; } /** * decode codabar code * @param row row to cecode */ codaBarDecodeRow(row) { const code = []; const barThreshold = Math.ceil(row.reduce((pre, item) => (pre + item) / 2, 0)); // Read one encoded character at a time. while (row.length > 0) { const seg = row.splice(0, 8).splice(0, 7); const key = seg.map(len => (len < barThreshold ? 'n' : 'w')).join(''); if (this.CODA_BAR_CHAR_SET[key] === undefined) return null; code.push(this.CODA_BAR_CHAR_SET[key]); } let strCode = code.join(''); if (this.validCodaBarString(strCode)) return strCode; return null; } /** * check if the string is a CodaBar string * @param src string to determine */ validCodaBarString(src) { let reg = /^[A-D].{1,}[A-D]$/; return reg.test(src); } }