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
This commit is contained in:
srowen 2008-10-07 09:53:53 +00:00
parent 089df8eb7b
commit 773409ed6a
4 changed files with 39 additions and 14 deletions

View file

@ -107,15 +107,12 @@ public final class BitArray {
mask |= 1 << j; mask |= 1 << j;
} }
} }
if (value) {
if ((bits[i] & mask) != mask) { // 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 false;
} }
} else {
if ((bits[i] & mask) != 0) {
return false;
}
}
} }
return true; return true;
} }

View file

@ -93,8 +93,8 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements
int start = startRange[0]; int start = startRange[0];
nextStart = startRange[1]; nextStart = startRange[1];
// As a check, we want to see some white in front of this "start pattern", // As a check, we want to see some white in front of this "start pattern",
// maybe as wide as the start pattern itself? // maybe as wide as the 150% of the start pattern itself?
foundStart = row.isRange(Math.max(0, start - (3 * (startRange[1] - start)) / 2), start, false); foundStart = row.isRange(Math.max(0, start - (3 * (nextStart - start)) / 2), start, false);
} }
return startRange; return startRange;
} }
@ -108,7 +108,7 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements
int endStart = decodeMiddle(row, startGuardRange, result); int endStart = decodeMiddle(row, startGuardRange, result);
int[] endRange = decodeEnd(row, endStart); 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]; int end = endRange[1];
if (!row.isRange(end, Math.min(row.getSize(), end + (3 * (end - endRange[0])) / 2), false)) { if (!row.isRange(end, Math.min(row.getSize(), end + (3 * (end - endRange[0])) / 2), false)) {
throw new ReaderException("Pattern not followed by whitespace"); throw new ReaderException("Pattern not followed by whitespace");

View file

@ -194,8 +194,11 @@ public final class Code128Reader extends AbstractOneDReader {
} }
} }
if (bestMatch >= 0) { if (bestMatch >= 0) {
// 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}; return new int[]{patternStart, i, bestMatch};
} }
}
patternStart += counters[0] + counters[1]; patternStart += counters[0] + counters[1];
for (int y = 2; y < patternLength; y++) { for (int y = 2; y < patternLength; y++) {
counters[y - 2] = counters[y]; counters[y - 2] = counters[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 // Pull out from sum the value of the penultimate check code
checksumTotal -= multiplier * lastCode; checksumTotal -= multiplier * lastCode;
// lastCode is the checksum then: // lastCode is the checksum then:

View file

@ -26,7 +26,7 @@ import com.google.zxing.common.GenericResultPoint;
import java.util.Hashtable; import java.util.Hashtable;
/** /**
* <p>Decodes Code 39 barcodes. This does not supported "Full ASCII Code 39" yet.</p> * <p>Decodes Code 39 barcodes. This does not support "Full ASCII Code 39" yet.</p>
* *
* @author srowen@google.com (Sean Owen) * @author srowen@google.com (Sean Owen)
*/ */
@ -122,6 +122,18 @@ public final class Code39Reader extends AbstractOneDReader {
} while (decodedChar != '*'); } while (decodedChar != '*');
result.deleteCharAt(result.length() - 1); // remove asterisk 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) { if (usingCheckDigit) {
int max = result.length() - 1; int max = result.length() - 1;
int total = 0; int total = 0;
@ -180,8 +192,11 @@ public final class Code39Reader extends AbstractOneDReader {
if (counterPosition == patternLength - 1) { if (counterPosition == patternLength - 1) {
try { try {
if (toNarrowWidePattern(counters) == ASTERISK_ENCODING) { if (toNarrowWidePattern(counters) == ASTERISK_ENCODING) {
// 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}; return new int[]{patternStart, i};
} }
}
} catch (ReaderException re) { } catch (ReaderException re) {
// no match, continue // no match, continue
} }