From f2200f8ebe0f0eef72b8b916d085506a94c774b0 Mon Sep 17 00:00:00 2001 From: srowen Date: Mon, 31 May 2010 12:49:29 +0000 Subject: [PATCH] Update Codabar style and disable it as its causing too many false positives git-svn-id: http://zxing.googlecode.com/svn/trunk@1403 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- .../com/google/zxing/MultiFormatReader.java | 2 +- .../com/google/zxing/oned/CodaBarReader.java | 288 ++++++++---------- .../zxing/oned/MultiFormatOneDReader.java | 3 +- .../zxing/client/j2se/CommandLineRunner.java | 2 +- .../com/google/zxing/web/DecodeServlet.java | 3 +- 5 files changed, 135 insertions(+), 163 deletions(-) diff --git a/core/src/com/google/zxing/MultiFormatReader.java b/core/src/com/google/zxing/MultiFormatReader.java index aab25ff3..9784760c 100644 --- a/core/src/com/google/zxing/MultiFormatReader.java +++ b/core/src/com/google/zxing/MultiFormatReader.java @@ -99,7 +99,7 @@ public final class MultiFormatReader implements Reader { formats.contains(BarcodeFormat.UPC_E) || formats.contains(BarcodeFormat.EAN_13) || formats.contains(BarcodeFormat.EAN_8) || - formats.contains(BarcodeFormat.CODABAR) || + //formats.contains(BarcodeFormat.CODABAR) || formats.contains(BarcodeFormat.CODE_39) || formats.contains(BarcodeFormat.CODE_93) || formats.contains(BarcodeFormat.CODE_128) || diff --git a/core/src/com/google/zxing/oned/CodaBarReader.java b/core/src/com/google/zxing/oned/CodaBarReader.java index ff677cbc..a3382b6b 100644 --- a/core/src/com/google/zxing/oned/CodaBarReader.java +++ b/core/src/com/google/zxing/oned/CodaBarReader.java @@ -16,144 +16,123 @@ package com.google.zxing.oned; +import java.util.Hashtable; + import com.google.zxing.BarcodeFormat; -import com.google.zxing.FormatException; import com.google.zxing.NotFoundException; import com.google.zxing.Result; import com.google.zxing.ResultPoint; import com.google.zxing.common.BitArray; -import java.util.Hashtable; /** - *

Decodes Codabar barcodes.

+ *

Decodes Codabar barcodes.

* * @author Bas Vijfwinkel */ public final class CodaBarReader extends OneDReader { - private static final String ALPHABET_STRING = "0123456789-$:/.+ABCDTN"; - private static final char[] ALPHABET = ALPHABET_STRING.toCharArray(); + private static final String ALPHABET_STRING = "0123456789-$:/.+ABCDTN"; + private static final char[] ALPHABET = ALPHABET_STRING.toCharArray(); + + /** + * These represent the encodings of characters, as patterns of wide and narrow bars. The 7 least-significant bits of + * each int correspond to the pattern of wide and narrow, with 1s representing "wide" and 0s representing narrow. NOTE + * : c is equal to the * pattern NOTE : d is equal to the e pattern + */ + private static final int[] CHARACTER_ENCODINGS = { + 0x003, 0x006, 0x009, 0x060, 0x012, 0x042, 0x021, 0x024, 0x030, 0x048, // 0-9 + 0x00c, 0x018, 0x025, 0x051, 0x054, 0x015, 0x01A, 0x029, 0x00B, 0x00E, // -$:/.+ABCD + 0x01A, 0x029 //TN + }; + + // multiple start/end patterns + // official start and end patterns + // some codabar generator allow the codabar string to be closed by every character + private static final char[] STARTEND_ENCODING = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '$', ':', '/', '.', '+', 'A', 'B', 'C', 'D', 'T', 'N'}; + + public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws NotFoundException { + int[] start = findAsteriskPattern(row); + start[1] = 0; // BAS: settings this to 0 improves the recognition rate somehow? + int nextStart = start[1]; + int end = row.getSize(); + + // Read off white space + while (nextStart < end && !row.get(nextStart)) { + nextStart++; + } - /** - * These represent the encodings of characters, as patterns of wide and narrow bars. - * The 7 least-significant bits of each int correspond to the pattern of wide and narrow, - * with 1s representing "wide" and 0s representing narrow. - * NOTE : c is equal to the * pattern - * NOTE : d is equal to the e pattern - */ + StringBuffer result = new StringBuffer(); + //int[] counters = new int[7]; + int[] counters; + int lastStart; - private static final int[] CHARACTER_ENCODINGS = { - 0x003, 0x006, 0x009, 0x060, 0x012, 0x042, 0x021, 0x024, 0x030, 0x048, // 0-9 - 0x00c, 0x018, 0x025, 0x051, 0x054, 0x015, 0x01A, 0x029, 0x00B, 0x00E, // -$:/.+ABCD - 0x01A,0x029 //TN - }; - - // multiple start/end patterns - // official start and end patterns - //private static final char[] STARTEND_ENCODING = {'$','A','B','C','D','T','N','+'}; - // some codabar generator allow the codabar string to be closed by every character - private static final char[] STARTEND_ENCODING = {'0','1','2','3','4','5','6','7','8','9','-','$',':','/','.','+','A','B','C','D','T','N'}; + do { + counters = new int[]{0, 0, 0, 0, 0, 0, 0}; // reset counters + recordPattern(row, nextStart, counters); - public CodaBarReader() - { - } + char decodedChar = toNarrowWidePattern(counters); + if (decodedChar == '!') { + throw NotFoundException.getNotFoundInstance(); + } + result.append(decodedChar); + lastStart = nextStart; + for (int i = 0; i < counters.length; i++) { + nextStart += counters[i]; + } + // Read off white space + while (nextStart < end && !row.get(nextStart)) { + nextStart++; + } + } while (nextStart < end); // no fixed end pattern so keep on reading while data is available + + // find last character in STARTEND_ENCODING + for (int k = result.length() - 1; k >= 0; k--) { + if (arrayContains(STARTEND_ENCODING, result.charAt(k))) { + // valid character -> remove and break out of loop + result.deleteCharAt(k); + k = -1;// break out of loop + } else { + // not a valid character -> remove anyway + result.deleteCharAt(k); + } + } - public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws FormatException, NotFoundException - { - int[] start; - start = findAsteriskPattern(row); - start[1] = 0; // BAS: settings this to 0 improves the recognition rate somehow? - int nextStart = start[1]; - int end = row.getSize(); - - // Read off white space - while (nextStart < end && !row.get(nextStart)) - { - nextStart++; - } - StringBuffer result = new StringBuffer(); - //int[] counters = new int[7]; - int[] counters; - char decodedChar; - int lastStart; - - do - { - counters = new int[] {0,0,0,0,0,0,0} ; // reset counters - recordPattern(row, nextStart, counters); - - decodedChar = toNarrowWidePattern(counters); - if (decodedChar == '!') - { - throw NotFoundException.getNotFoundInstance(); - } - result.append(decodedChar); - lastStart = nextStart; - for (int i = 0; i < counters.length; i++) - { - nextStart += counters[i]; - } - - // Read off white space - while (nextStart < end && !row.get(nextStart)) - { - nextStart++; - } - } while (nextStart < end); // no fixed end pattern so keep on reading while data is available + // remove first character + if (result.length() > 0) { + result.deleteCharAt(0); + } + + // Look for whitespace after pattern: + int lastPatternSize = 0; + for (int i = 0; i < counters.length; i++) { + lastPatternSize += counters[i]; + } + int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize; + // If 50% of last pattern size, following last pattern, is not whitespace, fail + // (but if it's whitespace to the very end of the image, that's OK) + if ((nextStart) != end && (whiteSpaceAfterEnd / 2 < lastPatternSize)) { + throw NotFoundException.getNotFoundInstance(); + } - // find last character in STARTEND_ENCODING - for (int k = result.length()-1;k >= 0;k--) - { - if (arrayContains(STARTEND_ENCODING,result.charAt(k))) - { - // valid character -> remove and break out of loop - result.deleteCharAt(k); - k=-1;// break out of loop - } - else - { - // not a valid character -> remove anyway - result.deleteCharAt(k); - } - } - - - // remove first character - if (result.length() > 0) {result.deleteCharAt(0);} - // Look for whitespace after pattern: - int lastPatternSize = 0; - for (int i = 0; i < counters.length; i++) - { - lastPatternSize += counters[i]; - } - int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize; - // If 50% of last pattern size, following last pattern, is not whitespace, fail - // (but if it's whitespace to the very end of the image, that's OK) - if ((nextStart) != end && (whiteSpaceAfterEnd / 2 < lastPatternSize)) - { - throw NotFoundException.getNotFoundInstance(); - } - + String resultString = result.toString(); + if (resultString.length() == 0) { + // Almost surely a false positive + throw NotFoundException.getNotFoundInstance(); + } - String resultString = result.toString(); - if (resultString.length() == 0) - { - // Almost surely a false positive - throw NotFoundException.getNotFoundInstance(); - } - - float left = (float) (start[1] + start[0]) / 2.0f; - float right = (float) (nextStart + lastStart) / 2.0f; - return new Result( - resultString, - null, - new ResultPoint[]{ - new ResultPoint(left, (float) rowNumber), - new ResultPoint(right, (float) rowNumber)}, - BarcodeFormat.CODABAR); + float left = (float) (start[1] + start[0]) / 2.0f; + float right = (float) (nextStart + lastStart) / 2.0f; + return new Result( + resultString, + null, + new ResultPoint[]{ + new ResultPoint(left, (float) rowNumber), + new ResultPoint(right, (float) rowNumber)}, + BarcodeFormat.CODABAR); } private static int[] findAsteriskPattern(BitArray row) throws NotFoundException { @@ -179,8 +158,7 @@ public final class CodaBarReader extends OneDReader { } else { if (counterPosition == patternLength - 1) { try { - if (arrayContains(STARTEND_ENCODING,toNarrowWidePattern(counters))) - { + if (arrayContains(STARTEND_ENCODING, toNarrowWidePattern(counters))) { // Look for whitespace before start pattern, >= 50% of width of start pattern if (row.isRange(Math.max(0, patternStart - (i - patternStart) / 2), patternStart, false)) { return new int[]{patternStart, i}; @@ -206,60 +184,54 @@ public final class CodaBarReader extends OneDReader { throw NotFoundException.getNotFoundInstance(); } - private static boolean arrayContains(char[] array, char key) - { - if (array != null) - { - for (int i=0;i maxNarrowCounter) { maxNarrowCounter = counters[i]; } - } - // ---------- change end + int minCounter = Integer.MAX_VALUE; + for (int i = 0; i < numCounters; i++) { + if (counters[i] < minCounter) { + minCounter = counters[i]; + } + if (counters[i] > maxNarrowCounter) { + maxNarrowCounter = counters[i]; + } + } + // ---------- change end - do - { - wideCounters = 0; - int totalWideCountersWidth = 0; + do { + int wideCounters = 0; int pattern = 0; for (int i = 0; i < numCounters; i++) { - int counter = counters[i]; if (counters[i] > maxNarrowCounter) { pattern |= 1 << (numCounters - 1 - i); wideCounters++; - totalWideCountersWidth += counter; } } - - if ((wideCounters == 2) || (wideCounters == 3)) - { - for (int i = 0; i < CHARACTER_ENCODINGS.length; i++) - { - if (CHARACTER_ENCODINGS[i] == pattern) - { - return ALPHABET[i]; - } - } + + if ((wideCounters == 2) || (wideCounters == 3)) { + for (int i = 0; i < CHARACTER_ENCODINGS.length; i++) { + if (CHARACTER_ENCODINGS[i] == pattern) { + return ALPHABET[i]; + } + } } - maxNarrowCounter--; + maxNarrowCounter--; } while (maxNarrowCounter > minCounter); return '!'; } diff --git a/core/src/com/google/zxing/oned/MultiFormatOneDReader.java b/core/src/com/google/zxing/oned/MultiFormatOneDReader.java index f92af71f..fa3de5d9 100644 --- a/core/src/com/google/zxing/oned/MultiFormatOneDReader.java +++ b/core/src/com/google/zxing/oned/MultiFormatOneDReader.java @@ -65,7 +65,6 @@ public final class MultiFormatOneDReader extends OneDReader { if (possibleFormats.contains(BarcodeFormat.CODABAR)) { readers.addElement(new CodaBarReader()); } - if (possibleFormats.contains(BarcodeFormat.RSS14)) { readers.addElement(new RSS14Reader()); } @@ -76,7 +75,7 @@ public final class MultiFormatOneDReader extends OneDReader { if (readers.isEmpty()) { readers.addElement(new MultiFormatUPCEANReader(hints)); readers.addElement(new Code39Reader()); - readers.addElement(new CodaBarReader()); + //readers.addElement(new CodaBarReader()); readers.addElement(new Code93Reader()); readers.addElement(new Code128Reader()); readers.addElement(new ITFReader()); diff --git a/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java b/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java index 2721ff85..8b7edd00 100644 --- a/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java +++ b/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java @@ -122,7 +122,7 @@ public final class CommandLineRunner { vector.addElement(BarcodeFormat.QR_CODE); vector.addElement(BarcodeFormat.DATAMATRIX); vector.addElement(BarcodeFormat.PDF417); - vector.addElement(BarcodeFormat.CODABAR); + //vector.addElement(BarcodeFormat.CODABAR); } hints.put(DecodeHintType.POSSIBLE_FORMATS, vector); if (tryHarder) { diff --git a/zxingorg/src/com/google/zxing/web/DecodeServlet.java b/zxingorg/src/com/google/zxing/web/DecodeServlet.java index 0a26eca7..8419c7ac 100644 --- a/zxingorg/src/com/google/zxing/web/DecodeServlet.java +++ b/zxingorg/src/com/google/zxing/web/DecodeServlet.java @@ -101,7 +101,7 @@ public final class DecodeServlet extends HttpServlet { static { HINTS = new Hashtable(5); HINTS.put(DecodeHintType.TRY_HARDER, Boolean.TRUE); - Collection possibleFormats = new Vector(); + Collection possibleFormats = new Vector(17); possibleFormats.add(BarcodeFormat.UPC_A); possibleFormats.add(BarcodeFormat.UPC_E); possibleFormats.add(BarcodeFormat.EAN_8); @@ -109,6 +109,7 @@ public final class DecodeServlet extends HttpServlet { possibleFormats.add(BarcodeFormat.CODE_39); possibleFormats.add(BarcodeFormat.CODE_93); possibleFormats.add(BarcodeFormat.CODE_128); + //possibleFormats.add(BarcodeFormat.CODABAR); possibleFormats.add(BarcodeFormat.ITF); possibleFormats.add(BarcodeFormat.RSS14); possibleFormats.add(BarcodeFormat.QR_CODE); -- 2.20.1