Use TRY_HARDER hint in javase CommandLineRunner. TRY_HARDER now tries rotating the...
authorsrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Mon, 3 Mar 2008 19:48:08 +0000 (19:48 +0000)
committersrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Mon, 3 Mar 2008 19:48:08 +0000 (19:48 +0000)
git-svn-id: http://zxing.googlecode.com/svn/trunk@235 59b500cc-1b3d-0410-9834-0bbf25fbcc57

android/src/com/google/zxing/client/android/YUVMonochromeBitmapSource.java
core/src/com/google/zxing/DecodeHintType.java
core/src/com/google/zxing/MonochromeBitmapSource.java
core/src/com/google/zxing/MultiFormatReader.java
core/src/com/google/zxing/oned/AbstractOneDReader.java
core/src/com/google/zxing/oned/MultiFormatOneDReader.java
core/src/com/google/zxing/oned/MultiFormatUPCEANReader.java
javame/src/com/google/zxing/client/j2me/LCDUIImageMonochromeBitmapSource.java
javase/src/com/google/zxing/client/j2se/BufferedImageMonochromeBitmapSource.java
javase/src/com/google/zxing/client/j2se/CommandLineRunner.java

index e2614c1..3df1855 100755 (executable)
@@ -114,4 +114,12 @@ final class YUVMonochromeBitmapSource implements MonochromeBitmapSource {
     return lastMethod;
   }
 
+  public MonochromeBitmapSource rotateCounterClockwise() {
+    throw new IllegalStateException("Rotate not supported");
+  }
+
+  public boolean isRotatedSupported() {
+    return false;
+  }
+
 }
\ No newline at end of file
index 8ab4bac..a8e1c83 100644 (file)
@@ -21,26 +21,35 @@ package com.google.zxing;
  * more quickly or accurately decode it. It is up to implementations to decide what,
  * if anything, to do with the information that is supplied.
  *
- * @author srowen@google.com (Sean Owen), dswitkin@google.com (Daniel Switkin)
+ * @author srowen@google.com (Sean Owen)
+ * @author dswitkin@google.com (Daniel Switkin)
  * @see Reader#decode(MonochromeBitmapSource, java.util.Hashtable)
  */
 public final class DecodeHintType {
 
   // No, we can't use an enum here. J2ME doesn't support it.
 
-  /** Unspecified, application-specific hint. */
+  /**
+   * Unspecified, application-specific hint. Maps to an unspecified {@link Object}.
+   */
   public static final DecodeHintType OTHER = new DecodeHintType();
 
-  /** Image is a pure monochrome image of a barcode. */
+  /**
+   * Image is a pure monochrome image of a barcode. Doesn't matter what it maps to;
+   * use {@link Boolean#TRUE}.
+   */
   public static final DecodeHintType PURE_BARCODE = new DecodeHintType();
 
   /**
    * Image is known to be of one of a few possible formats.
-   * Maps to a collection of {@link BarcodeFormat}s.
+   * Maps to a {@link java.util.Vector} of {@link BarcodeFormat}s.
    */
   public static final DecodeHintType POSSIBLE_FORMATS = new DecodeHintType();
 
-  /** Spend more time to try to find a barcode; optimize for accuracy, not speed. */
+  /**
+   * Spend more time to try to find a barcode; optimize for accuracy, not speed.
+   * Doesn't matter what it maps to; use {@link Boolean#TRUE}.
+   */
   public static final DecodeHintType TRY_HARDER = new DecodeHintType();
 
   private DecodeHintType() {
index 180970e..799a6e1 100644 (file)
@@ -76,4 +76,23 @@ public interface MonochromeBitmapSource {
    */
   BlackPointEstimationMethod getLastEstimationMethod();
 
+  /**
+   * <p>Optional operation which returns an implementation based on the same underlying
+   * image, but which behaves as if the underlying image had been rotated 90 degrees
+   * counterclockwise. This is useful in the context of 1D barcodes and the
+   * {@link DecodeHintType#TRY_HARDER} decode hint, and is only intended to be
+   * used in non-resource-constrained environments. Hence, implementations
+   * of this class which are only used in resource-constrained mobile environments
+   * don't have a need to implement this.</p>
+   *
+   * @throws IllegalStateException if not supported
+   */
+  MonochromeBitmapSource rotateCounterClockwise();
+
+  /**
+   * @return true iff rotation is supported
+   * @see #rotateCounterClockwise()
+   */
+  boolean isRotatedSupported();
+
 }
index 9d1fc02..3032422 100644 (file)
@@ -37,7 +37,7 @@ public final class MultiFormatReader implements Reader {
 
   public Result decode(MonochromeBitmapSource image, Hashtable hints) throws ReaderException {
 
-    Hashtable possibleFormats = hints == null ? null : (Hashtable) hints.get(DecodeHintType.POSSIBLE_FORMATS);
+    Vector possibleFormats = hints == null ? null : (Vector) hints.get(DecodeHintType.POSSIBLE_FORMATS);
     Vector readers = new Vector();
     if (possibleFormats != null) {
       if (possibleFormats.contains(BarcodeFormat.UPC_A) ||
index f107a48..a543f31 100644 (file)
@@ -39,8 +39,20 @@ public abstract class AbstractOneDReader implements OneDReader {
   }
 
   public final Result decode(MonochromeBitmapSource image, Hashtable hints) throws ReaderException {
+    boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
+    try {
+      return doDecode(image, hints, tryHarder);
+    } catch (ReaderException re) {
+      if (tryHarder && image.isRotatedSupported()) {
+        MonochromeBitmapSource rotatedImage = image.rotateCounterClockwise();
+        return doDecode(rotatedImage, hints, tryHarder);        
+      } else {
+        throw re;
+      }
+    }
+  }
 
-    boolean tryHarder = hints != null && hints.contains(DecodeHintType.TRY_HARDER);
+  private Result doDecode(MonochromeBitmapSource image, Hashtable hints, boolean tryHarder) throws ReaderException {
 
     int width = image.getWidth();
     int height = image.getHeight();
index 0963745..df47b89 100644 (file)
@@ -33,7 +33,7 @@ public final class MultiFormatOneDReader extends AbstractOneDReader {
 
   public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws ReaderException {
 
-    Hashtable possibleFormats = hints == null ? null : (Hashtable) hints.get(DecodeHintType.POSSIBLE_FORMATS);
+    Vector possibleFormats = hints == null ? null : (Vector) hints.get(DecodeHintType.POSSIBLE_FORMATS);
     Vector readers = new Vector();
     if (possibleFormats != null) {
       if (possibleFormats.contains(BarcodeFormat.EAN_13) ||
index dff4ad5..835504b 100644 (file)
@@ -35,7 +35,7 @@ import java.util.Vector;
 public final class MultiFormatUPCEANReader extends AbstractOneDReader {
 
   public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws ReaderException {
-    Hashtable possibleFormats = hints == null ? null : (Hashtable) hints.get(DecodeHintType.POSSIBLE_FORMATS);
+    Vector possibleFormats = hints == null ? null : (Vector) hints.get(DecodeHintType.POSSIBLE_FORMATS);
     Vector readers = new Vector();
     if (possibleFormats != null) {
       if (possibleFormats.contains(BarcodeFormat.EAN_13)) {
index 6430971..3f1e374 100644 (file)
@@ -108,6 +108,14 @@ public final class LCDUIImageMonochromeBitmapSource implements MonochromeBitmapS
     return lastMethod;
   }
 
+  public MonochromeBitmapSource rotateCounterClockwise() {
+    throw new IllegalStateException("Rotate not supported");
+  }
+
+  public boolean isRotatedSupported() {
+    return false;
+  }
+
   /**
    * Extracts luminance from a pixel from this source. By default, the source is assumed to use RGB,
    * so this implementation computes luminance is a function of a red, green and blue components as
index e17dc25..92174bb 100644 (file)
@@ -21,7 +21,10 @@ import com.google.zxing.MonochromeBitmapSource;
 import com.google.zxing.common.BitArray;
 import com.google.zxing.common.BlackPointEstimator;
 
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
 import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
 
 /**
  * <p>An implementation based upon {@link BufferedImage}. This provides access to the
@@ -112,6 +115,19 @@ public final class BufferedImageMonochromeBitmapSource implements MonochromeBitm
     return lastMethod;
   }
 
+  public MonochromeBitmapSource rotateCounterClockwise() {
+    // 90 degrees counterclockwise:
+    AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, image.getHeight());
+    BufferedImageOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
+    BufferedImage rotatedImage = new BufferedImage(image.getHeight(), image.getWidth(), image.getType());
+    op.filter(image, rotatedImage);
+    return new BufferedImageMonochromeBitmapSource(rotatedImage);
+  }
+
+  public boolean isRotatedSupported() {
+    return true;
+  }
+
   /**
    * Extracts luminance from a pixel from this source. By default, the source is assumed to use RGB,
    * so this implementation computes luminance is a function of a red, green and blue components as
index a6d2335..d27b3a4 100644 (file)
@@ -16,6 +16,7 @@
 
 package com.google.zxing.client.j2se;
 
+import com.google.zxing.DecodeHintType;
 import com.google.zxing.MultiFormatReader;
 import com.google.zxing.ReaderException;
 
@@ -24,6 +25,7 @@ import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
+import java.util.Hashtable;
 
 /**
  * <p>Simply attempts to decode the barcode in the image indicated by the single argument
@@ -62,8 +64,10 @@ public final class CommandLineRunner {
       return false;
     }
     try {
+      Hashtable hints = new Hashtable();
+      hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
       BufferedImageMonochromeBitmapSource source = new BufferedImageMonochromeBitmapSource(image);
-      String result = new MultiFormatReader().decode(source).getText();
+      String result = new MultiFormatReader().decode(source, hints).getText();
       System.out.println(uri.toString() + ": " + result);
       return true;
     } catch (ReaderException e) {