Add Code 93 support. Update tests to reflect new (better) number of successes.
authorsrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Sun, 30 May 2010 14:37:08 +0000 (14:37 +0000)
committersrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Sun, 30 May 2010 14:37:08 +0000 (14:37 +0000)
git-svn-id: http://zxing.googlecode.com/svn/trunk@1398 59b500cc-1b3d-0410-9834-0bbf25fbcc57

28 files changed:
android-integration/src/com/google/zxing/integration/android/IntentIntegrator.java
core/src/com/google/zxing/BarcodeFormat.java
core/src/com/google/zxing/MultiFormatReader.java
core/src/com/google/zxing/oned/Code39Reader.java
core/src/com/google/zxing/oned/Code93Reader.java [new file with mode: 0644]
core/src/com/google/zxing/oned/MultiFormatOneDReader.java
core/src/com/google/zxing/oned/OneDReader.java
core/test/data/blackbox/code93-1/1.gif [new file with mode: 0644]
core/test/data/blackbox/code93-1/1.txt [new file with mode: 0644]
core/test/data/blackbox/code93-1/2.gif [new file with mode: 0644]
core/test/data/blackbox/code93-1/2.txt [new file with mode: 0644]
core/test/data/blackbox/code93-1/3.jpg [new file with mode: 0644]
core/test/data/blackbox/code93-1/3.txt [new file with mode: 0644]
core/test/src/com/google/zxing/oned/Code128BlackBox2TestCase.java
core/test/src/com/google/zxing/oned/Code93BlackBox1TestCase.java [new file with mode: 0644]
core/test/src/com/google/zxing/oned/EAN13BlackBox1TestCase.java
core/test/src/com/google/zxing/oned/EAN13BlackBox2TestCase.java
core/test/src/com/google/zxing/oned/EAN13BlackBox3TestCase.java
core/test/src/com/google/zxing/oned/ITFBlackBox1TestCase.java
core/test/src/com/google/zxing/oned/ITFBlackBox2TestCase.java
core/test/src/com/google/zxing/oned/UPCABlackBox1TestCase.java
core/test/src/com/google/zxing/oned/UPCABlackBox2TestCase.java
core/test/src/com/google/zxing/oned/UPCABlackBox3ReflectiveTestCase.java
core/test/src/com/google/zxing/oned/UPCABlackBox4TestCase.java
core/test/src/com/google/zxing/oned/UPCEBlackBox2TestCase.java
core/test/src/com/google/zxing/oned/UPCEBlackBox3ReflectiveTestCase.java
javase/src/com/google/zxing/client/j2se/CommandLineRunner.java
zxingorg/src/com/google/zxing/web/DecodeServlet.java

index b92f86c..c6c8214 100644 (file)
@@ -87,7 +87,7 @@ public final class IntentIntegrator {
 
   // supported barcode formats
   public static final String PRODUCT_CODE_TYPES = "UPC_A,UPC_E,EAN_8,EAN_13";
-  public static final String ONE_D_CODE_TYPES = PRODUCT_CODE_TYPES + ",CODE_39,CODE_128";
+  public static final String ONE_D_CODE_TYPES = PRODUCT_CODE_TYPES + ",CODE_39,CODE_93,CODE_128";
   public static final String QR_CODE_TYPES = "QR_CODE";
   public static final String ALL_CODE_TYPES = null;
 
index d4e1e70..aa4096a 100644 (file)
@@ -53,6 +53,9 @@ public final class BarcodeFormat {
   /** Code 39 1D format. */
   public static final BarcodeFormat CODE_39 = new BarcodeFormat("CODE_39");
 
+  /** Code 93 1D format. */
+  public static final BarcodeFormat CODE_93 = new BarcodeFormat("CODE_93");
+
   /** ITF (Interleaved Two of Five) 1D format. */
   public static final BarcodeFormat ITF = new BarcodeFormat("ITF");
 
index c198021..0e70341 100644 (file)
@@ -100,6 +100,7 @@ public final class MultiFormatReader implements Reader {
               formats.contains(BarcodeFormat.EAN_13) ||
               formats.contains(BarcodeFormat.EAN_8) ||
               formats.contains(BarcodeFormat.CODE_39) ||
+              formats.contains(BarcodeFormat.CODE_93) ||
               formats.contains(BarcodeFormat.CODE_128) ||
               formats.contains(BarcodeFormat.ITF) ||
               formats.contains(BarcodeFormat.RSS14) || 
index 50c0ede..0bc66bf 100644 (file)
@@ -30,6 +30,7 @@ import java.util.Hashtable;
  * <p>Decodes Code 39 barcodes. This does not support "Full ASCII Code 39" yet.</p>
  *
  * @author Sean Owen
+ * @see Code93Reader
  */
 public final class Code39Reader extends OneDReader {
 
@@ -143,22 +144,24 @@ public final class Code39Reader extends OneDReader {
       for (int i = 0; i < max; i++) {
         total += ALPHABET_STRING.indexOf(result.charAt(i));
       }
-      if (total % 43 != ALPHABET_STRING.indexOf(result.charAt(max))) {
+      if (result.charAt(max) != ALPHABET[total % 43]) {
         throw ChecksumException.getChecksumInstance();
       }
       result.deleteCharAt(max);
     }
 
-    String resultString = result.toString();
-    if (extendedMode) {
-      resultString = decodeExtended(resultString);
-    }
-
-    if (resultString.length() == 0) {
+    if (result.length() == 0) {
       // Almost surely a false positive
       throw NotFoundException.getNotFoundInstance();
     }
 
+    String resultString;
+    if (extendedMode) {
+      resultString = decodeExtended(result);
+    } else {
+      resultString = result.toString();
+    }
+
     float left = (float) (start[1] + start[0]) / 2.0f;
     float right = (float) (nextStart + lastStart) / 2.0f;
     return new Result(
@@ -271,7 +274,7 @@ public final class Code39Reader extends OneDReader {
     throw NotFoundException.getNotFoundInstance();
   }
 
-  private static String decodeExtended(String encoded) throws FormatException {
+  private static String decodeExtended(StringBuffer encoded) throws FormatException {
     int length = encoded.length();
     StringBuffer decoded = new StringBuffer(length);
     for (int i = 0; i < length; i++) {
diff --git a/core/src/com/google/zxing/oned/Code93Reader.java b/core/src/com/google/zxing/oned/Code93Reader.java
new file mode 100644 (file)
index 0000000..3435169
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2010 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.oned;
+
+import java.util.Hashtable;
+
+import com.google.zxing.BarcodeFormat;
+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;
+
+/**
+ * <p>Decodes Code 93 barcodes.</p>
+ *
+ * @author Sean Owen
+ * @see Code39Reader
+ */
+public final class Code93Reader extends OneDReader {
+
+  // Note that 'abcd' are dummy characters in place of control characters.
+  private static final String ALPHABET_STRING = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd*";
+  private static final char[] ALPHABET = ALPHABET_STRING.toCharArray();
+
+  /**
+   * These represent the encodings of characters, as patterns of wide and narrow bars.
+   * The 9 least-significant bits of each int correspond to the pattern of wide and narrow.
+   */
+  private static final int[] CHARACTER_ENCODINGS = {
+      0x114, 0x148, 0x144, 0x142, 0x128, 0x124, 0x122, 0x150, 0x112, 0x10A, // 0-9
+      0x1A8, 0x1A4, 0x1A2, 0x194, 0x192, 0x18A, 0x168, 0x164, 0x162, 0x134, // A-J
+      0x11A, 0x158, 0x14C, 0x146, 0x12C, 0x116, 0x1B4, 0x1B2, 0x1AC, 0x1A6, // K-T
+      0x196, 0x19A, 0x16C, 0x166, 0x136, 0x13A, // U-Z
+      0x12E, 0x1D4, 0x1D2, 0x1CA, 0x16E, 0x176, 0x1AE, // - - %
+      0x126, 0x1DA, 0x1D6, 0x132, 0x15E, // Control chars? $-*
+  };
+  private static final int ASTERISK_ENCODING = CHARACTER_ENCODINGS[47];
+
+  public Result decodeRow(int rowNumber, BitArray row, Hashtable hints)
+      throws NotFoundException, ChecksumException, FormatException {
+
+    int[] start = findAsteriskPattern(row);
+    int nextStart = start[1];
+    int end = row.getSize();
+
+    // Read off white space
+    while (nextStart < end && !row.get(nextStart)) {
+      nextStart++;
+    }
+
+    StringBuffer result = new StringBuffer(20);
+    int[] counters = new int[6];
+    char decodedChar;
+    int lastStart;
+    do {
+      recordPattern(row, nextStart, counters);
+      int pattern = toPattern(counters);
+      if (pattern < 0) {
+        throw NotFoundException.getNotFoundInstance();
+      }
+      decodedChar = patternToChar(pattern);
+      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 (decodedChar != '*');
+    result.deleteCharAt(result.length() - 1); // remove asterisk
+
+    // Should be at least one more black module
+    if (nextStart == end || !row.get(nextStart)) {
+      throw NotFoundException.getNotFoundInstance();
+    }
+
+    if (result.length() < 2) {
+      // Almost surely a false positive
+      throw NotFoundException.getNotFoundInstance();
+    }
+
+    checkChecksums(result);
+    // Remove checksum digits
+    result.setLength(result.length() - 2);
+
+    String resultString = decodeExtended(result);
+
+    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.CODE_93);
+
+  }
+
+  private static int[] findAsteriskPattern(BitArray row) throws NotFoundException {
+    int width = row.getSize();
+    int rowOffset = 0;
+    while (rowOffset < width) {
+      if (row.get(rowOffset)) {
+        break;
+      }
+      rowOffset++;
+    }
+
+    int counterPosition = 0;
+    int[] counters = new int[6];
+    int patternStart = rowOffset;
+    boolean isWhite = false;
+    int patternLength = counters.length;
+
+    for (int i = rowOffset; i < width; i++) {
+      boolean pixel = row.get(i);
+      if (pixel ^ isWhite) {
+        counters[counterPosition]++;
+      } else {
+        if (counterPosition == patternLength - 1) {
+          if (toPattern(counters) == ASTERISK_ENCODING) {
+            return new int[]{patternStart, i};
+          }
+          patternStart += counters[0] + counters[1];
+          for (int y = 2; y < patternLength; y++) {
+            counters[y - 2] = counters[y];
+          }
+          counters[patternLength - 2] = 0;
+          counters[patternLength - 1] = 0;
+          counterPosition--;
+        } else {
+          counterPosition++;
+        }
+        counters[counterPosition] = 1;
+        isWhite = !isWhite;
+      }
+    }
+    throw NotFoundException.getNotFoundInstance();
+  }
+
+  private static int toPattern(int[] counters) {
+    int max = counters.length;
+    int sum = 0;
+    for (int i = 0; i < max; i++) {
+      sum += counters[i];
+    }
+    int pattern = 0;
+    for (int i = 0; i < max; i++) {
+      int scaledShifted = (counters[i] << INTEGER_MATH_SHIFT) * 9 / sum;
+      int scaledUnshifted = scaledShifted >> INTEGER_MATH_SHIFT;
+      if ((scaledShifted & 0xFF) > 0x7F) {
+        scaledUnshifted++;
+      }
+      if (scaledUnshifted < 1 || scaledUnshifted > 4) {
+        return -1;
+      }
+      if ((i & 0x01) == 0) {
+        for (int j = 0; j < scaledUnshifted; j++) {
+          pattern = (pattern << 1) | 0x01;
+        }
+      } else {
+        pattern <<= scaledUnshifted;
+      }
+    }
+    return pattern;
+  }
+
+  private static char patternToChar(int pattern) throws NotFoundException {
+    for (int i = 0; i < CHARACTER_ENCODINGS.length; i++) {
+      if (CHARACTER_ENCODINGS[i] == pattern) {
+        return ALPHABET[i];
+      }
+    }
+    throw NotFoundException.getNotFoundInstance();
+  }
+
+  private static String decodeExtended(StringBuffer encoded) throws FormatException {
+    int length = encoded.length();
+    StringBuffer decoded = new StringBuffer(length);
+    for (int i = 0; i < length; i++) {
+      char c = encoded.charAt(i);
+      if (c >= 'a' && c <= 'd') {
+        char next = encoded.charAt(i + 1);
+        char decodedChar = '\0';
+        switch (c) {
+          case 'd':
+            // +A to +Z map to a to z
+            if (next >= 'A' && next <= 'Z') {
+              decodedChar = (char) (next + 32);
+            } else {
+              throw FormatException.getFormatInstance();
+            }
+            break;
+          case 'a':
+            // $A to $Z map to control codes SH to SB
+            if (next >= 'A' && next <= 'Z') {
+              decodedChar = (char) (next - 64);
+            } else {
+              throw FormatException.getFormatInstance();
+            }
+            break;
+          case 'b':
+            // %A to %E map to control codes ESC to US
+            if (next >= 'A' && next <= 'E') {
+              decodedChar = (char) (next - 38);
+            } else if (next >= 'F' && next <= 'W') {
+              decodedChar = (char) (next - 11);
+            } else {
+              throw FormatException.getFormatInstance();
+            }
+            break;
+          case 'c':
+            // /A to /O map to ! to , and /Z maps to :
+            if (next >= 'A' && next <= 'O') {
+              decodedChar = (char) (next - 32);
+            } else if (next == 'Z') {
+              decodedChar = ':';
+            } else {
+              throw FormatException.getFormatInstance();
+            }
+            break;
+        }
+        decoded.append(decodedChar);
+        // bump up i again since we read two characters
+        i++;
+      } else {
+        decoded.append(c);
+      }
+    }
+    return decoded.toString();
+  }
+
+  private static void checkChecksums(StringBuffer result) throws ChecksumException {
+    int length = result.length();
+    checkOneChecksum(result, length - 2, 20);
+    checkOneChecksum(result, length - 1, 15);
+  }
+
+  private static void checkOneChecksum(StringBuffer result, int checkPosition, int weightMax)
+      throws ChecksumException {
+    int weight = 1;
+    int total = 0;
+    for (int i = checkPosition - 1; i >= 0; i--) {
+      total += weight * ALPHABET_STRING.indexOf(result.charAt(i));
+      if (++weight > weightMax) {
+        weight = 1;
+      }
+    }
+    if (result.charAt(checkPosition) != ALPHABET[total % 47]) {
+      throw ChecksumException.getChecksumInstance();
+    }
+  }
+
+}
index ccf63dd..2e3126f 100644 (file)
@@ -53,6 +53,9 @@ public final class MultiFormatOneDReader extends OneDReader {
       if (possibleFormats.contains(BarcodeFormat.CODE_39)) {
         readers.addElement(new Code39Reader(useCode39CheckDigit));
       }
+      if (possibleFormats.contains(BarcodeFormat.CODE_93)) {
+        readers.addElement(new Code93Reader());
+      }
       if (possibleFormats.contains(BarcodeFormat.CODE_128)) {
         readers.addElement(new Code128Reader());
       }
@@ -69,6 +72,7 @@ public final class MultiFormatOneDReader extends OneDReader {
     if (readers.isEmpty()) {
       readers.addElement(new MultiFormatUPCEANReader(hints));
       readers.addElement(new Code39Reader());
+      readers.addElement(new Code93Reader());      
       readers.addElement(new Code128Reader());
       readers.addElement(new ITFReader());
       readers.addElement(new RSS14Reader());      
index bad1f6a..102483c 100644 (file)
@@ -40,7 +40,7 @@ import java.util.Hashtable;
  */
 public abstract class OneDReader implements Reader {
 
-  private static final int INTEGER_MATH_SHIFT = 8;
+  protected static final int INTEGER_MATH_SHIFT = 8;
   protected static final int PATTERN_MATCH_RESULT_SCALE_FACTOR = 1 << INTEGER_MATH_SHIFT;
 
   public Result decode(BinaryBitmap image) throws NotFoundException, FormatException {
diff --git a/core/test/data/blackbox/code93-1/1.gif b/core/test/data/blackbox/code93-1/1.gif
new file mode 100644 (file)
index 0000000..bc629ed
Binary files /dev/null and b/core/test/data/blackbox/code93-1/1.gif differ
diff --git a/core/test/data/blackbox/code93-1/1.txt b/core/test/data/blackbox/code93-1/1.txt
new file mode 100644 (file)
index 0000000..6a537b5
--- /dev/null
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/core/test/data/blackbox/code93-1/2.gif b/core/test/data/blackbox/code93-1/2.gif
new file mode 100644 (file)
index 0000000..3647cee
Binary files /dev/null and b/core/test/data/blackbox/code93-1/2.gif differ
diff --git a/core/test/data/blackbox/code93-1/2.txt b/core/test/data/blackbox/code93-1/2.txt
new file mode 100644 (file)
index 0000000..f6df9d7
--- /dev/null
@@ -0,0 +1 @@
+CODE 93
\ No newline at end of file
diff --git a/core/test/data/blackbox/code93-1/3.jpg b/core/test/data/blackbox/code93-1/3.jpg
new file mode 100644 (file)
index 0000000..b36c503
Binary files /dev/null and b/core/test/data/blackbox/code93-1/3.jpg differ
diff --git a/core/test/data/blackbox/code93-1/3.txt b/core/test/data/blackbox/code93-1/3.txt
new file mode 100644 (file)
index 0000000..418d6c3
--- /dev/null
@@ -0,0 +1 @@
+DATA
\ No newline at end of file
index b2fb164..1e134fd 100644 (file)
@@ -27,8 +27,8 @@ public final class Code128BlackBox2TestCase extends AbstractBlackBoxTestCase {
 
   public Code128BlackBox2TestCase() {
     super("test/data/blackbox/code128-2", new MultiFormatReader(), BarcodeFormat.CODE_128);
-    addTest(33, 39, 0.0f);
-    addTest(34, 39, 180.0f);
+    addTest(35, 39, 0.0f);
+    addTest(36, 39, 180.0f);
   }
 
 }
\ No newline at end of file
diff --git a/core/test/src/com/google/zxing/oned/Code93BlackBox1TestCase.java b/core/test/src/com/google/zxing/oned/Code93BlackBox1TestCase.java
new file mode 100644 (file)
index 0000000..f8f1d87
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.oned;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.common.AbstractBlackBoxTestCase;
+
+/**
+ * @author Sean Owen
+ */
+public final class Code93BlackBox1TestCase extends AbstractBlackBoxTestCase {
+
+  public Code93BlackBox1TestCase() {
+    super("test/data/blackbox/code93-1", new MultiFormatReader(), BarcodeFormat.CODE_93);
+    addTest(3, 3, 0.0f);
+    addTest(3, 3, 180.0f);
+  }
+
+}
\ No newline at end of file
index 07ee093..61fc135 100644 (file)
@@ -27,8 +27,8 @@ public final class EAN13BlackBox1TestCase extends AbstractBlackBoxTestCase {
 
   public EAN13BlackBox1TestCase() {
     super("test/data/blackbox/ean13-1", new MultiFormatReader(), BarcodeFormat.EAN_13);
-    addTest(28, 31, 0.0f);
-    addTest(26, 31, 180.0f);
+    addTest(29, 31, 0.0f);
+    addTest(27, 31, 180.0f);
   }
 
 }
\ No newline at end of file
index 6f7a98d..155dd01 100644 (file)
@@ -29,7 +29,7 @@ public final class EAN13BlackBox2TestCase extends AbstractBlackBoxTestCase {
 
   public EAN13BlackBox2TestCase() {
     super("test/data/blackbox/ean13-2", new MultiFormatReader(), BarcodeFormat.EAN_13);
-    addTest(10, 16, 0.0f);
+    addTest(11, 16, 0.0f);
     addTest(10, 16, 180.0f);
   }
 
index 0070031..a114993 100644 (file)
@@ -27,8 +27,8 @@ public final class EAN13BlackBox3TestCase extends AbstractBlackBoxTestCase {
 
   public EAN13BlackBox3TestCase() {
     super("test/data/blackbox/ean13-3", new MultiFormatReader(), BarcodeFormat.EAN_13);
-    addTest(49, 55, 0.0f);
-    addTest(52, 55, 180.0f);
+    addTest(53, 55, 0.0f);
+    addTest(55, 55, 180.0f);
   }
 
 }
index ad488dc..64050c9 100644 (file)
@@ -28,7 +28,7 @@ public final class ITFBlackBox1TestCase extends AbstractBlackBoxTestCase {
   public ITFBlackBox1TestCase() {\r
     super("test/data/blackbox/itf-1", new MultiFormatReader(), BarcodeFormat.ITF);\r
     addTest(9, 12, 0.0f);\r
-    addTest(8, 12, 180.0f);\r
+    addTest(12, 12, 180.0f);\r
   }\r
 \r
 }\r
index 72f321c..58ff0a6 100644 (file)
@@ -28,7 +28,7 @@ public final class ITFBlackBox2TestCase extends AbstractBlackBoxTestCase {
   public ITFBlackBox2TestCase() {\r
     super("test/data/blackbox/itf-2", new MultiFormatReader(), BarcodeFormat.ITF);\r
     addTest(8, 9, 0.0f);\r
-    addTest(8, 9, 180.0f);\r
+    addTest(7, 9, 180.0f);\r
   }\r
 \r
 }\r
index 84784c7..50bbb84 100644 (file)
@@ -27,8 +27,8 @@ public final class UPCABlackBox1TestCase extends AbstractBlackBoxTestCase {
 
   public UPCABlackBox1TestCase() {
     super("test/data/blackbox/upca-1", new MultiFormatReader(), BarcodeFormat.UPC_A);
-    addTest(15, 18, 0.0f);
-    addTest(15, 18, 180.0f);
+    addTest(16, 18, 0.0f);
+    addTest(17, 18, 180.0f);
   }
 
 }
\ No newline at end of file
index 8adccd7..297680d 100644 (file)
@@ -27,8 +27,8 @@ public final class UPCABlackBox2TestCase extends AbstractBlackBoxTestCase {
 
   public UPCABlackBox2TestCase() {
     super("test/data/blackbox/upca-2", new MultiFormatReader(), BarcodeFormat.UPC_A);
-    addTest(25, 35, 0.0f);
-    addTest(25, 35, 180.0f);
+    addTest(29, 35, 0.0f);
+    addTest(31, 35, 180.0f);
   }
 
 }
index b1c4dbc..2bd3455 100644 (file)
@@ -27,8 +27,8 @@ public final class UPCABlackBox3ReflectiveTestCase extends AbstractBlackBoxTestC
 
   public UPCABlackBox3ReflectiveTestCase() {
     super("test/data/blackbox/upca-3", new MultiFormatReader(), BarcodeFormat.UPC_A);
-    addTest(8, 8, 0.0f);
-    addTest(6, 9, 180.0f);
+    addTest(7, 8, 0.0f);
+    addTest(7, 9, 180.0f);
   }
 
 }
index 7c20af6..a188873 100644 (file)
@@ -27,8 +27,8 @@ public final class UPCABlackBox4TestCase extends AbstractBlackBoxTestCase {
 
   public UPCABlackBox4TestCase() {
     super("test/data/blackbox/upca-4", new MultiFormatReader(), BarcodeFormat.UPC_A);
-    addTest(7, 11, 0.0f);
-    addTest(8, 11, 180.0f);
+    addTest(8, 11, 0.0f);
+    addTest(9, 11, 180.0f);
   }
 
 }
index 885402a..6c322a7 100644 (file)
@@ -28,7 +28,7 @@ public final class UPCEBlackBox2TestCase extends AbstractBlackBoxTestCase {
   public UPCEBlackBox2TestCase() {
     super("test/data/blackbox/upce-2", new MultiFormatReader(), BarcodeFormat.UPC_E);
     addTest(30, 35, 0.0f);
-    addTest(29, 35, 180.0f);
+    addTest(31, 35, 180.0f);
   }
 
 }
index 0cc9b4a..766356c 100644 (file)
@@ -27,8 +27,8 @@ public final class UPCEBlackBox3ReflectiveTestCase extends AbstractBlackBoxTestC
 
   public UPCEBlackBox3ReflectiveTestCase() {
     super("test/data/blackbox/upce-3", new MultiFormatReader(), BarcodeFormat.UPC_E);
-    addTest(4, 8, 0.0f);
-    addTest(4, 8, 180.0f);
+    addTest(6, 8, 0.0f);
+    addTest(6, 8, 180.0f);
   }
 
 }
index 8ac1de4..8777337 100644 (file)
@@ -116,6 +116,7 @@ public final class CommandLineRunner {
     vector.addElement(BarcodeFormat.RSS14);    
     if (!productsOnly) {
       vector.addElement(BarcodeFormat.CODE_39);
+      vector.addElement(BarcodeFormat.CODE_93);      
       vector.addElement(BarcodeFormat.CODE_128);
       vector.addElement(BarcodeFormat.ITF);
       vector.addElement(BarcodeFormat.QR_CODE);
index 70a3555..0a26eca 100644 (file)
@@ -107,6 +107,7 @@ public final class DecodeServlet extends HttpServlet {
     possibleFormats.add(BarcodeFormat.EAN_8);
     possibleFormats.add(BarcodeFormat.EAN_13);
     possibleFormats.add(BarcodeFormat.CODE_39);
+    possibleFormats.add(BarcodeFormat.CODE_93);    
     possibleFormats.add(BarcodeFormat.CODE_128);
     possibleFormats.add(BarcodeFormat.ITF);
     possibleFormats.add(BarcodeFormat.RSS14);