Changed validation method in order to prevent false positives on other 1D barcodes
authorbas5winkel <bas5winkel@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Tue, 1 Jun 2010 14:39:24 +0000 (14:39 +0000)
committerbas5winkel <bas5winkel@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Tue, 1 Jun 2010 14:39:24 +0000 (14:39 +0000)
git-svn-id: http://zxing.googlecode.com/svn/trunk@1407 59b500cc-1b3d-0410-9834-0bbf25fbcc57

core/src/com/google/zxing/oned/CodaBarReader.java

index a3382b6..703d947 100644 (file)
@@ -45,11 +45,20 @@ public final class CodaBarReader extends OneDReader {
       0x01A, 0x029 //TN\r
   };\r
 \r
+  // minimal number of characters that should be present (inclusing start and stop characters)\r
+  // this check has been added to reduce the number of false positive on other formats\r
+  // until the cause for this behaviour has been determined\r
+  // under normal circumstances this should be set to 3\r
+  private static final int minCharacterLength = 6; \r
+  \r
   // multiple start/end patterns\r
   // official start and end patterns\r
+  private static final char[] STARTEND_ENCODING = {'E', '*', '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 = {\r
-      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '$', ':', '/', '.', '+', 'A', 'B', 'C', 'D', 'T', 'N'};\r
+  //private static final char[] STARTEND_ENCODING = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '$', ':', '/', '.', '+', 'A', 'B', 'C', 'D', 'T', 'N'};\r
+  \r
+  // some industries use a checksum standard but this is not part of the original codabar standard\r
+  // for more information see : http://www.mecsw.com/specs/codabar.html\r
 \r
   public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws NotFoundException {\r
     int[] start = findAsteriskPattern(row);\r
@@ -87,29 +96,12 @@ public final class CodaBarReader extends OneDReader {
       }\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
-\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
+\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
@@ -117,17 +109,49 @@ public final class CodaBarReader extends OneDReader {
       throw NotFoundException.getNotFoundInstance();\r
     }\r
 \r
-\r
-    String resultString = result.toString();\r
-    if (resultString.length() == 0) {\r
-      // Almost surely a false positive\r
-      throw NotFoundException.getNotFoundInstance();\r
+       // valid result?\r
+       if (result.length() < 2)\r
+       {\r
+               throw NotFoundException.getNotFoundInstance();\r
+       }\r
+       \r
+       char startchar = result.charAt(0);\r
+       if (!arrayContains(STARTEND_ENCODING, startchar))\r
+       {\r
+               //invalid start character\r
+               throw NotFoundException.getNotFoundInstance();\r
+       }\r
+    \r
+       // find stop character\r
+    for (int k = 1;k < result.length() ;k++) \r
+       {\r
+      if (result.charAt(k) == startchar) \r
+         {\r
+        // found stop character -> discard rest of the string\r
+               if ((k+1) != result.length())\r
+               {\r
+                       result.delete(k+1,result.length()-1);\r
+                       k = result.length();// break out of loop\r
+               } \r
+         }\r
     }\r
 \r
+    // remove stop/start characters character and check if a string longer than 5 characters is contained\r
+    if (result.length() > minCharacterLength) \r
+       { \r
+               result.deleteCharAt(result.length()-1); \r
+               result.deleteCharAt(0); \r
+       }\r
+       else\r
+       {\r
+               // Almost surely a false positive ( start + stop + at least 1 character)\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
+        result.toString(),\r
         null,\r
         new ResultPoint[]{\r
             new ResultPoint(left, (float) rowNumber),\r