Use TRY_HARDER hint in javase CommandLineRunner. TRY_HARDER now tries rotating the image when dealing with 1D barcodes. Clarified and fixed value type of several items in the "hints" Hashtables.
git-svn-id: https://zxing.googlecode.com/svn/trunk@235 59b500cc-1b3d-0410-9834-0bbf25fbcc57
diff --git a/android/src/com/google/zxing/client/android/YUVMonochromeBitmapSource.java b/android/src/com/google/zxing/client/android/YUVMonochromeBitmapSource.java
index e2614c1..3df1855 100755
--- a/android/src/com/google/zxing/client/android/YUVMonochromeBitmapSource.java
+++ b/android/src/com/google/zxing/client/android/YUVMonochromeBitmapSource.java
@@ -114,4 +114,12 @@
return lastMethod;
}
+ public MonochromeBitmapSource rotateCounterClockwise() {
+ throw new IllegalStateException("Rotate not supported");
+ }
+
+ public boolean isRotatedSupported() {
+ return false;
+ }
+
}
\ No newline at end of file
diff --git a/core/src/com/google/zxing/DecodeHintType.java b/core/src/com/google/zxing/DecodeHintType.java
index 8ab4bac..a8e1c83 100644
--- a/core/src/com/google/zxing/DecodeHintType.java
+++ b/core/src/com/google/zxing/DecodeHintType.java
@@ -21,26 +21,35 @@
* 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() {
diff --git a/core/src/com/google/zxing/MonochromeBitmapSource.java b/core/src/com/google/zxing/MonochromeBitmapSource.java
index 180970e..799a6e1 100644
--- a/core/src/com/google/zxing/MonochromeBitmapSource.java
+++ b/core/src/com/google/zxing/MonochromeBitmapSource.java
@@ -76,4 +76,23 @@
*/
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();
+
}
diff --git a/core/src/com/google/zxing/MultiFormatReader.java b/core/src/com/google/zxing/MultiFormatReader.java
index 9d1fc02..3032422 100644
--- a/core/src/com/google/zxing/MultiFormatReader.java
+++ b/core/src/com/google/zxing/MultiFormatReader.java
@@ -37,7 +37,7 @@
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) ||
diff --git a/core/src/com/google/zxing/oned/AbstractOneDReader.java b/core/src/com/google/zxing/oned/AbstractOneDReader.java
index f107a48..a543f31 100644
--- a/core/src/com/google/zxing/oned/AbstractOneDReader.java
+++ b/core/src/com/google/zxing/oned/AbstractOneDReader.java
@@ -39,8 +39,20 @@
}
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();
diff --git a/core/src/com/google/zxing/oned/MultiFormatOneDReader.java b/core/src/com/google/zxing/oned/MultiFormatOneDReader.java
index 0963745..df47b89 100644
--- a/core/src/com/google/zxing/oned/MultiFormatOneDReader.java
+++ b/core/src/com/google/zxing/oned/MultiFormatOneDReader.java
@@ -33,7 +33,7 @@
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) ||
diff --git a/core/src/com/google/zxing/oned/MultiFormatUPCEANReader.java b/core/src/com/google/zxing/oned/MultiFormatUPCEANReader.java
index dff4ad5..835504b 100644
--- a/core/src/com/google/zxing/oned/MultiFormatUPCEANReader.java
+++ b/core/src/com/google/zxing/oned/MultiFormatUPCEANReader.java
@@ -35,7 +35,7 @@
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)) {
diff --git a/javame/src/com/google/zxing/client/j2me/LCDUIImageMonochromeBitmapSource.java b/javame/src/com/google/zxing/client/j2me/LCDUIImageMonochromeBitmapSource.java
index 6430971..3f1e374 100644
--- a/javame/src/com/google/zxing/client/j2me/LCDUIImageMonochromeBitmapSource.java
+++ b/javame/src/com/google/zxing/client/j2me/LCDUIImageMonochromeBitmapSource.java
@@ -108,6 +108,14 @@
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
diff --git a/javase/src/com/google/zxing/client/j2se/BufferedImageMonochromeBitmapSource.java b/javase/src/com/google/zxing/client/j2se/BufferedImageMonochromeBitmapSource.java
index e17dc25..92174bb 100644
--- a/javase/src/com/google/zxing/client/j2se/BufferedImageMonochromeBitmapSource.java
+++ b/javase/src/com/google/zxing/client/j2se/BufferedImageMonochromeBitmapSource.java
@@ -21,7 +21,10 @@
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 @@
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
diff --git a/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java b/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java
index a6d2335..d27b3a4 100644
--- a/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java
+++ b/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java
@@ -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.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 @@
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) {