Add Code 93 support. Update tests to reflect new (better) number of successes.
[zxing.git] / core / src / com / google / zxing / oned / Code128Reader.java
index b921af4..b41d954 100644 (file)
@@ -17,7 +17,9 @@
 package com.google.zxing.oned;
 
 import com.google.zxing.BarcodeFormat;
-import com.google.zxing.ReaderException;
+import com.google.zxing.ChecksumException;
+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;
@@ -29,9 +31,9 @@ import java.util.Hashtable;
  *
  * @author Sean Owen
  */
-public final class Code128Reader extends AbstractOneDReader {
+public final class Code128Reader extends OneDReader {
 
-  private static final int[][] CODE_PATTERNS = {
+  static final int[][] CODE_PATTERNS = {
       {2, 1, 2, 2, 2, 2}, // 0
       {2, 2, 2, 1, 2, 2},
       {2, 2, 2, 2, 2, 1},
@@ -161,7 +163,7 @@ public final class Code128Reader extends AbstractOneDReader {
   private static final int CODE_START_C = 105;
   private static final int CODE_STOP = 106;
 
-  private static int[] findStartPattern(BitArray row) throws ReaderException {
+  private static int[] findStartPattern(BitArray row) throws NotFoundException {
     int width = row.getSize();
     int rowOffset = 0;
     while (rowOffset < width) {
@@ -194,7 +196,7 @@ public final class Code128Reader extends AbstractOneDReader {
             }
           }
           if (bestMatch >= 0) {
-            // Look for whitespace before start pattern, >= 50% of width of start pattern            
+            // 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, bestMatch};
@@ -211,13 +213,13 @@ public final class Code128Reader extends AbstractOneDReader {
           counterPosition++;
         }
         counters[counterPosition] = 1;
-        isWhite ^= true; // isWhite = !isWhite;
+        isWhite = !isWhite;
       }
     }
-    throw ReaderException.getInstance();
+    throw NotFoundException.getNotFoundInstance();
   }
 
-  private static int decodeCode(BitArray row, int[] counters, int rowOffset) throws ReaderException {
+  private static int decodeCode(BitArray row, int[] counters, int rowOffset) throws NotFoundException {
     recordPattern(row, rowOffset, counters);
     int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
     int bestMatch = -1;
@@ -233,11 +235,12 @@ public final class Code128Reader extends AbstractOneDReader {
     if (bestMatch >= 0) {
       return bestMatch;
     } else {
-      throw ReaderException.getInstance();
+      throw NotFoundException.getNotFoundInstance();
     }
   }
 
-  public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws ReaderException {
+  public Result decodeRow(int rowNumber, BitArray row, Hashtable hints)
+      throws NotFoundException, FormatException, ChecksumException {
 
     int[] startPatternInfo = findStartPattern(row);
     int startCode = startPatternInfo[2];
@@ -253,13 +256,13 @@ public final class Code128Reader extends AbstractOneDReader {
         codeSet = CODE_CODE_C;
         break;
       default:
-        throw ReaderException.getInstance();
+        throw FormatException.getFormatInstance();
     }
 
     boolean done = false;
     boolean isNextShifted = false;
 
-    StringBuffer result = new StringBuffer();
+    StringBuffer result = new StringBuffer(20);
     int lastStart = startPatternInfo[0];
     int nextStart = startPatternInfo[1];
     int[] counters = new int[6];
@@ -303,7 +306,7 @@ public final class Code128Reader extends AbstractOneDReader {
         case CODE_START_A:
         case CODE_START_B:
         case CODE_START_C:
-          throw ReaderException.getInstance();
+          throw FormatException.getFormatInstance();
       }
 
       switch (codeSet) {
@@ -420,19 +423,20 @@ public final class Code128Reader extends AbstractOneDReader {
     // Check for ample whitespace following pattern, but, to do this we first need to remember that
     // we fudged decoding CODE_STOP since it actually has 7 bars, not 6. There is a black bar left
     // to read off. Would be slightly better to properly read. Here we just skip it:
-    while (row.get(nextStart)) {
+    int width = row.getSize();
+    while (nextStart < width && row.get(nextStart)) {
       nextStart++;
     }
-    if (!row.isRange(nextStart, Math.min(row.getSize(), nextStart + (nextStart - lastStart) / 2),
+    if (!row.isRange(nextStart, Math.min(width, nextStart + (nextStart - lastStart) / 2),
         false)) {
-      throw ReaderException.getInstance();
+      throw NotFoundException.getNotFoundInstance();
     }
 
     // Pull out from sum the value of the penultimate check code
     checksumTotal -= multiplier * lastCode;
     // lastCode is the checksum then:
     if (checksumTotal % 103 != lastCode) {
-      throw ReaderException.getInstance();
+      throw ChecksumException.getChecksumInstance();
     }
 
     // Need to pull out the check digits from string
@@ -451,7 +455,7 @@ public final class Code128Reader extends AbstractOneDReader {
 
     if (resultString.length() == 0) {
       // Almost surely a false positive
-      throw ReaderException.getInstance();
+      throw FormatException.getFormatInstance();
     }
 
     float left = (float) (startPatternInfo[1] + startPatternInfo[0]) / 2.0f;