From 773409ed6a33f969c8e1da656ec7717e5b6ca1f7 Mon Sep 17 00:00:00 2001 From: srowen Date: Tue, 7 Oct 2008 09:53:53 +0000 Subject: [PATCH] Add check for minimal whitespace before/after Code 128, Code 39; a few code tweaks as well git-svn-id: https://zxing.googlecode.com/svn/trunk@601 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- .../src/com/google/zxing/common/BitArray.java | 13 +++++-------- .../zxing/oned/AbstractUPCEANReader.java | 6 +++--- .../com/google/zxing/oned/Code128Reader.java | 15 ++++++++++++++- .../com/google/zxing/oned/Code39Reader.java | 19 +++++++++++++++++-- 4 files changed, 39 insertions(+), 14 deletions(-) diff --git a/core/src/com/google/zxing/common/BitArray.java b/core/src/com/google/zxing/common/BitArray.java index e5eead099..7d419ab27 100644 --- a/core/src/com/google/zxing/common/BitArray.java +++ b/core/src/com/google/zxing/common/BitArray.java @@ -107,14 +107,11 @@ public final class BitArray { mask |= 1 << j; } } - if (value) { - if ((bits[i] & mask) != mask) { - return false; - } - } else { - if ((bits[i] & mask) != 0) { - return false; - } + + // Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is, + // equals the mask, or we're looking for 0s and the masked portion is not all 0s + if ((bits[i] & mask) != (value ? mask : 0)) { + return false; } } return true; diff --git a/core/src/com/google/zxing/oned/AbstractUPCEANReader.java b/core/src/com/google/zxing/oned/AbstractUPCEANReader.java index e90066813..3ffc28b03 100644 --- a/core/src/com/google/zxing/oned/AbstractUPCEANReader.java +++ b/core/src/com/google/zxing/oned/AbstractUPCEANReader.java @@ -93,8 +93,8 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements int start = startRange[0]; nextStart = startRange[1]; // As a check, we want to see some white in front of this "start pattern", - // maybe as wide as the start pattern itself? - foundStart = row.isRange(Math.max(0, start - (3 * (startRange[1] - start)) / 2), start, false); + // maybe as wide as the 150% of the start pattern itself? + foundStart = row.isRange(Math.max(0, start - (3 * (nextStart - start)) / 2), start, false); } return startRange; } @@ -108,7 +108,7 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements int endStart = decodeMiddle(row, startGuardRange, result); int[] endRange = decodeEnd(row, endStart); - // Check for whitespace after the pattern + // Check for whitespace after the pattern -- 150% of size of end pattern int end = endRange[1]; if (!row.isRange(end, Math.min(row.getSize(), end + (3 * (end - endRange[0])) / 2), false)) { throw new ReaderException("Pattern not followed by whitespace"); diff --git a/core/src/com/google/zxing/oned/Code128Reader.java b/core/src/com/google/zxing/oned/Code128Reader.java index 969a341d9..4063d11e5 100644 --- a/core/src/com/google/zxing/oned/Code128Reader.java +++ b/core/src/com/google/zxing/oned/Code128Reader.java @@ -194,7 +194,10 @@ public final class Code128Reader extends AbstractOneDReader { } } if (bestMatch >= 0) { - return new int[]{patternStart, i, bestMatch}; + // 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, bestMatch}; + } } patternStart += counters[0] + counters[1]; for (int y = 2; y < patternLength; y++) { @@ -413,6 +416,16 @@ public final class Code128Reader extends AbstractOneDReader { } + // Check for ample whitespice following pattern, but, to do this we first need to remember that we + // fudged decoding CODE_STOP since it actually has 7 bars, not 6. There is a black bar left to read off. + // Would be slightly better to properly read. Here we just skip it: + while (row.get(nextStart)) { + nextStart++; + } + if (!row.isRange(nextStart, Math.min(row.getSize(), nextStart + (nextStart - lastStart) / 2), false)) { + throw new ReaderException("Pattern not followed by whitespace"); + } + // Pull out from sum the value of the penultimate check code checksumTotal -= multiplier * lastCode; // lastCode is the checksum then: diff --git a/core/src/com/google/zxing/oned/Code39Reader.java b/core/src/com/google/zxing/oned/Code39Reader.java index e5f3fd9f4..4d69d6b8d 100644 --- a/core/src/com/google/zxing/oned/Code39Reader.java +++ b/core/src/com/google/zxing/oned/Code39Reader.java @@ -26,7 +26,7 @@ import com.google.zxing.common.GenericResultPoint; import java.util.Hashtable; /** - *

Decodes Code 39 barcodes. This does not supported "Full ASCII Code 39" yet.

+ *

Decodes Code 39 barcodes. This does not support "Full ASCII Code 39" yet.

* * @author srowen@google.com (Sean Owen) */ @@ -122,6 +122,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 +192,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