Another round of optimization, focused on reusing arrays and small objects.
[zxing.git] / core / src / com / google / zxing / oned / Code39Reader.java
index 36ff24c..4273c4f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Google Inc.
+ * 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.
@@ -26,7 +26,7 @@ import com.google.zxing.common.GenericResultPoint;
 import java.util.Hashtable;
 
 /**
- * <p>Decodes Code 39 barcodes. This does not supported "Full ASCII Code 39" yet.</p>
+ * <p>Decodes Code 39 barcodes. This does not support "Full ASCII Code 39" yet.</p>
  *
  * @author srowen@google.com (Sean Owen)
  */
@@ -92,9 +92,7 @@ public final class Code39Reader extends AbstractOneDReader {
   public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws ReaderException {
 
     int[] start = findAsteriskPattern(row);
-
     int nextStart = start[1];
-
     int end = row.getSize();
 
     // Read off white space
@@ -122,6 +120,18 @@ public final class Code39Reader extends AbstractOneDReader {
     } while (decodedChar != '*');
     result.deleteCharAt(result.length() - 1); // remove asterisk
 
+    // 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 new ReaderException("Pattern not followed by whitespace");
+    }
+
     if (usingCheckDigit) {
       int max = result.length() - 1;
       int total = 0;
@@ -180,7 +190,10 @@ public final class Code39Reader extends AbstractOneDReader {
         if (counterPosition == patternLength - 1) {
           try {
             if (toNarrowWidePattern(counters) == ASTERISK_ENCODING) {
-              return new int[]{patternStart, i};
+              // 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};
+              }
             }
           } catch (ReaderException re) {
             // no match, continue