Update Codabar style and disable it as its causing too many false positives
[zxing.git] / core / src / com / google / zxing / oned / CodaBarReader.java
index ff677cb..a3382b6 100644 (file)
 \r
 package com.google.zxing.oned;\r
 \r
+import java.util.Hashtable;\r
+\r
 import com.google.zxing.BarcodeFormat;\r
-import com.google.zxing.FormatException;\r
 import com.google.zxing.NotFoundException;\r
 import com.google.zxing.Result;\r
 import com.google.zxing.ResultPoint;\r
 import com.google.zxing.common.BitArray;\r
-import java.util.Hashtable;\r
 \r
 /**\r
- * <p>Decodes Codabar barcodes. </p>\r
+ * <p>Decodes Codabar barcodes.</p>\r
  *\r
  * @author Bas Vijfwinkel\r
  */\r
 public final class CodaBarReader extends OneDReader {\r
 \r
-       private static  final String ALPHABET_STRING = "0123456789-$:/.+ABCDTN";\r
-       private static final char[] ALPHABET = ALPHABET_STRING.toCharArray();\r
+  private static final String ALPHABET_STRING = "0123456789-$:/.+ABCDTN";\r
+  private static final char[] ALPHABET = ALPHABET_STRING.toCharArray();\r
+\r
+  /**\r
+   * These represent the encodings of characters, as patterns of wide and narrow bars. The 7 least-significant bits of\r
+   * each int correspond to the pattern of wide and narrow, with 1s representing "wide" and 0s representing narrow. NOTE\r
+   * : c is equal to the  * pattern NOTE : d is equal to the e pattern\r
+   */\r
+  private static final int[] CHARACTER_ENCODINGS = {\r
+      0x003, 0x006, 0x009, 0x060, 0x012, 0x042, 0x021, 0x024, 0x030, 0x048, // 0-9\r
+      0x00c, 0x018, 0x025, 0x051, 0x054, 0x015, 0x01A, 0x029, 0x00B, 0x00E, // -$:/.+ABCD\r
+      0x01A, 0x029 //TN\r
+  };\r
+\r
+  // multiple start/end patterns\r
+  // official start and end patterns\r
+  // some codabar generator allow the codabar string to be closed by every character\r
+  private static final char[] STARTEND_ENCODING = {\r
+      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '$', ':', '/', '.', '+', 'A', 'B', 'C', 'D', 'T', 'N'};\r
+\r
+  public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws NotFoundException {\r
+    int[] start = findAsteriskPattern(row);\r
+    start[1] = 0; // BAS: settings this to 0 improves the recognition rate somehow?\r
+    int nextStart = start[1];\r
+    int end = row.getSize();\r
+\r
+    // Read off white space\r
+    while (nextStart < end && !row.get(nextStart)) {\r
+      nextStart++;\r
+    }\r
 \r
-       /**\r
-    * These represent the encodings of characters, as patterns of wide and narrow bars.\r
-    * The 7 least-significant bits of each int correspond to the pattern of wide and narrow,\r
-    * with 1s representing "wide" and 0s representing narrow.\r
-       * NOTE : c is equal to the  * pattern \r
-       * NOTE : d is equal to the e pattern\r
-    */\r
+    StringBuffer result = new StringBuffer();\r
+    //int[] counters = new int[7];\r
+    int[] counters;\r
+    int lastStart;\r
 \r
-       private static final int[] CHARACTER_ENCODINGS = {\r
-        0x003, 0x006, 0x009, 0x060, 0x012, 0x042, 0x021, 0x024, 0x030, 0x048, // 0-9\r
-        0x00c, 0x018, 0x025, 0x051, 0x054, 0x015, 0x01A, 0x029, 0x00B, 0x00E, // -$:/.+ABCD\r
-        0x01A,0x029 //TN              \r
-        };\r
-       \r
-       // multiple start/end patterns\r
-       // official start and end patterns\r
-    //private static  final char[] STARTEND_ENCODING = {'$','A','B','C','D','T','N','+'}; \r
-       // some codabar generator allow the codabar string to be closed by every character\r
-       private static  final char[] STARTEND_ENCODING = {'0','1','2','3','4','5','6','7','8','9','-','$',':','/','.','+','A','B','C','D','T','N'}; \r
+    do {\r
+      counters = new int[]{0, 0, 0, 0, 0, 0, 0}; // reset counters\r
+      recordPattern(row, nextStart, counters);\r
 \r
-       public CodaBarReader() \r
-       {\r
-       }\r
+      char decodedChar = toNarrowWidePattern(counters);\r
+      if (decodedChar == '!') {\r
+        throw NotFoundException.getNotFoundInstance();\r
+      }\r
+      result.append(decodedChar);\r
+      lastStart = nextStart;\r
+      for (int i = 0; i < counters.length; i++) {\r
+        nextStart += counters[i];\r
+      }\r
 \r
+      // Read off white space\r
+      while (nextStart < end && !row.get(nextStart)) {\r
+        nextStart++;\r
+      }\r
+    } while (nextStart < end); // no fixed end pattern so keep on reading while data is available\r
+\r
+    // find last character in STARTEND_ENCODING\r
+    for (int k = result.length() - 1; k >= 0; k--) {\r
+      if (arrayContains(STARTEND_ENCODING, result.charAt(k))) {\r
+        // valid character -> remove and break out of loop\r
+        result.deleteCharAt(k);\r
+        k = -1;// break out of loop\r
+      } else {\r
+        // not a valid character -> remove anyway\r
+        result.deleteCharAt(k);\r
+      }\r
+    }\r
 \r
-    public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws FormatException, NotFoundException\r
-       {\r
-               int[] start;\r
-               start = findAsteriskPattern(row);\r
-               start[1] = 0; // BAS: settings this to 0 improves the recognition rate somehow?\r
-           int nextStart = start[1];\r
-               int end = row.getSize();\r
-               \r
-               // Read off white space\r
-               while (nextStart < end && !row.get(nextStart)) \r
-               {\r
-                       nextStart++;\r
-               }\r
 \r
-           StringBuffer result = new StringBuffer();\r
-               //int[] counters = new int[7];\r
-               int[] counters;\r
-               char decodedChar;\r
-               int lastStart;\r
-               \r
-           do \r
-               {\r
-                       counters = new int[] {0,0,0,0,0,0,0} ; // reset counters\r
-                       recordPattern(row, nextStart, counters);\r
-                       \r
-                       decodedChar = toNarrowWidePattern(counters);\r
-                       if (decodedChar == '!') \r
-                       {\r
-                               throw NotFoundException.getNotFoundInstance();\r
-                       }\r
-                       result.append(decodedChar);\r
-                       lastStart = nextStart;\r
-                       for (int i = 0; i < counters.length; i++) \r
-                       {\r
-                               nextStart += counters[i];\r
-                       }\r
-                       \r
-                       // Read off white space\r
-                       while (nextStart < end && !row.get(nextStart)) \r
-                       {\r
-                               nextStart++;\r
-                       }\r
-               } while (nextStart < end); // no fixed end pattern so keep on reading while data is available\r
+    // remove first character\r
+    if (result.length() > 0) {\r
+      result.deleteCharAt(0);\r
+    }\r
+\r
+    // Look for whitespace after pattern:\r
+    int lastPatternSize = 0;\r
+    for (int i = 0; i < counters.length; i++) {\r
+      lastPatternSize += counters[i];\r
+    }\r
+    int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;\r
+    // If 50% of last pattern size, following last pattern, is not whitespace, fail\r
+    // (but if it's whitespace to the very end of the image, that's OK)\r
+    if ((nextStart) != end && (whiteSpaceAfterEnd / 2 < lastPatternSize)) {\r
+      throw NotFoundException.getNotFoundInstance();\r
+    }\r
 \r
-               // find last character in STARTEND_ENCODING\r
-               for (int k = result.length()-1;k >= 0;k--)\r
-               {\r
-                       if (arrayContains(STARTEND_ENCODING,result.charAt(k)))\r
-                       {\r
-                               // valid character -> remove and break out of loop\r
-                               result.deleteCharAt(k);\r
-                               k=-1;// break out of loop\r
-                       }\r
-                       else\r
-                       {\r
-                               // not a valid character -> remove anyway\r
-                               result.deleteCharAt(k);\r
-                       }\r
-               }\r
-               \r
-               \r
-               // remove first character\r
-               if (result.length() > 0) {result.deleteCharAt(0);}\r
 \r
-               // Look for whitespace after pattern:\r
-        int lastPatternSize = 0;\r
-        for (int i = 0; i < counters.length; i++) \r
-               {\r
-              lastPatternSize += counters[i];\r
-        }\r
-        int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;\r
-        // If 50% of last pattern size, following last pattern, is not whitespace, fail\r
-         // (but if it's whitespace to the very end of the image, that's OK)\r
-        if ((nextStart) != end && (whiteSpaceAfterEnd / 2 < lastPatternSize)) \r
-               {\r
-              throw NotFoundException.getNotFoundInstance();\r
-        }\r
-               \r
+    String resultString = result.toString();\r
+    if (resultString.length() == 0) {\r
+      // Almost surely a false positive\r
+      throw NotFoundException.getNotFoundInstance();\r
+    }\r
 \r
-               String resultString = result.toString();\r
-               if (resultString.length() == 0) \r
-               {\r
-                 // Almost surely a false positive\r
-                 throw NotFoundException.getNotFoundInstance();\r
-               }\r
-               \r
-               float left = (float) (start[1] + start[0]) / 2.0f;\r
-               float right = (float) (nextStart + lastStart) / 2.0f;\r
-               return new Result(\r
-                                               resultString,\r
-                                               null,\r
-                                               new ResultPoint[]{\r
-                                                       new ResultPoint(left, (float) rowNumber),\r
-                                                       new ResultPoint(right, (float) rowNumber)},\r
-                                                       BarcodeFormat.CODABAR);\r
+    float left = (float) (start[1] + start[0]) / 2.0f;\r
+    float right = (float) (nextStart + lastStart) / 2.0f;\r
+    return new Result(\r
+        resultString,\r
+        null,\r
+        new ResultPoint[]{\r
+            new ResultPoint(left, (float) rowNumber),\r
+            new ResultPoint(right, (float) rowNumber)},\r
+        BarcodeFormat.CODABAR);\r
   }\r
 \r
   private static int[] findAsteriskPattern(BitArray row) throws NotFoundException {\r
@@ -179,8 +158,7 @@ public final class CodaBarReader extends OneDReader {
       } else {\r
         if (counterPosition == patternLength - 1) {\r
           try {\r
-                       if (arrayContains(STARTEND_ENCODING,toNarrowWidePattern(counters)))\r
-                       {\r
+            if (arrayContains(STARTEND_ENCODING, toNarrowWidePattern(counters))) {\r
               // Look for whitespace before start pattern, >= 50% of width of start pattern\r
               if (row.isRange(Math.max(0, patternStart - (i - patternStart) / 2), patternStart, false)) {\r
                 return new int[]{patternStart, i};\r
@@ -206,60 +184,54 @@ public final class CodaBarReader extends OneDReader {
     throw NotFoundException.getNotFoundInstance();\r
   }\r
 \r
-  private static boolean arrayContains(char[] array, char key)\r
-  {\r
-               if (array != null)\r
-               {\r
-                       for (int i=0;i<array.length;i++)\r
-                       {\r
-                               if (array[i] == key) { return true; }\r
-                       }\r
-               }\r
-               return false;\r
+  private static boolean arrayContains(char[] array, char key) {\r
+    if (array != null) {\r
+      for (int i = 0; i < array.length; i++) {\r
+        if (array[i] == key) {\r
+          return true;\r
+        }\r
+      }\r
+    }\r
+    return false;\r
   }\r
 \r
-    private static char toNarrowWidePattern(int[] counters) {\r
-       // BAS : I have changed the following part because some codabar images would fail with the original routine \r
-       //        I took from the Code39Reader.java file\r
-       // ----------- change start\r
+  private static char toNarrowWidePattern(int[] counters) {\r
+    // BAS : I have changed the following part because some codabar images would fail with the original routine\r
+    //        I took from the Code39Reader.java file\r
+    // ----------- change start\r
     int numCounters = counters.length;\r
     int maxNarrowCounter = 0;\r
-    int wideCounters;\r
 \r
-       int minCounter = Integer.MAX_VALUE;\r
-       for (int i = 0; i < numCounters; i++) \r
-       { \r
-               if (counters[i] < minCounter) { minCounter = counters[i]; }\r
-               if (counters[i] > maxNarrowCounter) { maxNarrowCounter = counters[i]; }\r
-       }\r
-       // ---------- change end        \r
+    int minCounter = Integer.MAX_VALUE;\r
+    for (int i = 0; i < numCounters; i++) {\r
+      if (counters[i] < minCounter) {\r
+        minCounter = counters[i];\r
+      }\r
+      if (counters[i] > maxNarrowCounter) {\r
+        maxNarrowCounter = counters[i];\r
+      }\r
+    }\r
+    // ---------- change end\r
 \r
 \r
-    do \r
-       {\r
-         wideCounters = 0;\r
-      int totalWideCountersWidth = 0;\r
+    do {\r
+      int wideCounters = 0;\r
       int pattern = 0;\r
       for (int i = 0; i < numCounters; i++) {\r
-        int counter = counters[i];\r
         if (counters[i] > maxNarrowCounter) {\r
           pattern |= 1 << (numCounters - 1 - i);\r
           wideCounters++;\r
-          totalWideCountersWidth += counter;\r
         }\r
       }\r
-         \r
-      if ((wideCounters == 2) || (wideCounters == 3)) \r
-         {\r
-        for (int i = 0; i < CHARACTER_ENCODINGS.length; i++) \r
-               {\r
-          if (CHARACTER_ENCODINGS[i] == pattern) \r
-                 {\r
-                       return ALPHABET[i];\r
-             }\r
-           }\r
+\r
+      if ((wideCounters == 2) || (wideCounters == 3)) {\r
+        for (int i = 0; i < CHARACTER_ENCODINGS.length; i++) {\r
+          if (CHARACTER_ENCODINGS[i] == pattern) {\r
+            return ALPHABET[i];\r
+          }\r
+        }\r
       }\r
-         maxNarrowCounter--;\r
+      maxNarrowCounter--;\r
     } while (maxNarrowCounter > minCounter);\r
     return '!';\r
   }\r