package com.google.zxing.oned;
import com.google.zxing.BarcodeFormat;
+import com.google.zxing.DecodeHintType;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.ResultPoint;
+import com.google.zxing.ResultPointCallback;
import com.google.zxing.common.BitArray;
import java.util.Hashtable;
*/
public abstract class AbstractUPCEANReader extends AbstractOneDReader implements UPCEANReader {
+ // These two values are critical for determining how permissive the decoding will be.
+ // We've arrived at these values through a lot of trial and error. Setting them any higher
+ // lets false positives creep in quickly.
private static final int MAX_AVG_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.42f);
private static final int MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.7f);
public final Result decodeRow(int rowNumber, BitArray row, Hashtable hints)
throws ReaderException {
- return decodeRow(rowNumber, row, findStartGuardPattern(row));
+ return decodeRow(rowNumber, row, findStartGuardPattern(row), hints);
}
- public final Result decodeRow(int rowNumber, BitArray row, int[] startGuardRange)
+ public final Result decodeRow(int rowNumber, BitArray row, int[] startGuardRange, Hashtable hints)
throws ReaderException {
+
+ ResultPointCallback resultPointCallback = hints == null ? null :
+ (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
+
+ if (resultPointCallback != null) {
+ resultPointCallback.foundPossibleResultPoint(new ResultPoint(
+ (startGuardRange[0] + startGuardRange[1]) / 2.0f, rowNumber
+ ));
+ }
+
StringBuffer result = decodeRowStringBuffer;
result.setLength(0);
int endStart = decodeMiddle(row, startGuardRange, result);
+
+ if (resultPointCallback != null) {
+ resultPointCallback.foundPossibleResultPoint(new ResultPoint(
+ endStart, rowNumber
+ ));
+ }
+
int[] endRange = decodeEnd(row, endStart);
+ if (resultPointCallback != null) {
+ resultPointCallback.foundPossibleResultPoint(new ResultPoint(
+ (endRange[0] + endRange[1]) / 2.0f, rowNumber
+ ));
+ }
+
+
// Make sure there is a quiet zone at least as big as the end pattern after the barcode. The
// spec might want more whitespace, but in practice this is the maximum we can count on.
int end = endRange[1];
abstract BarcodeFormat getBarcodeFormat();
/**
- * @return {@link #checkStandardUPCEANChecksum(String)}
+ * @return {@link #checkStandardUPCEANChecksum(String)}
*/
boolean checkChecksum(String s) throws ReaderException {
return checkStandardUPCEANChecksum(s);
counterPosition++;
}
counters[counterPosition] = 1;
- isWhite ^= true; // isWhite = !isWhite;
+ isWhite = !isWhite;
}
}
throw ReaderException.getInstance();