mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Update CodaBarReader.java
This commit is contained in:
parent
8944e60778
commit
cefd502bb3
|
@ -78,93 +78,112 @@ public final class CodaBarReader extends OneDReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result decodeRow(int rowNumber, BitArray row, Map<DecodeHintType,?> hints) throws NotFoundException {
|
public Result decodeRow(int rowNumber, BitArray row, Map<DecodeHintType, ?> hints) throws NotFoundException {
|
||||||
|
Arrays.fill(counters, 0);
|
||||||
|
setCounters(row);
|
||||||
|
|
||||||
|
int startOffset = findStartPattern();
|
||||||
|
int nextStart = startOffset;
|
||||||
|
decodeRowResult.setLength(0);
|
||||||
|
|
||||||
|
decodeCharacters(nextStart);
|
||||||
|
validateTrailingWhitespace(nextStart);
|
||||||
|
|
||||||
|
validatePattern(startOffset);
|
||||||
|
translateOffsetsToCharacters();
|
||||||
|
|
||||||
|
validateStartEndCharacters();
|
||||||
|
removeStartEndCharactersIfNeeded(hints);
|
||||||
|
|
||||||
|
float[] positions = calculateResultPositions(startOffset, nextStart);
|
||||||
|
return buildResult(rowNumber, positions);
|
||||||
|
}
|
||||||
|
|
||||||
Arrays.fill(counters, 0);
|
private void decodeCharacters(int nextStart) throws NotFoundException {
|
||||||
setCounters(row);
|
do {
|
||||||
int startOffset = findStartPattern();
|
int charOffset = toNarrowWidePattern(nextStart);
|
||||||
int nextStart = startOffset;
|
if (charOffset == -1) {
|
||||||
|
throw NotFoundException.getNotFoundInstance();
|
||||||
decodeRowResult.setLength(0);
|
}
|
||||||
do {
|
decodeRowResult.append((char) charOffset);
|
||||||
int charOffset = toNarrowWidePattern(nextStart);
|
nextStart += 8;
|
||||||
if (charOffset == -1) {
|
} while (nextStart < counterLength && !isEndCharacter());
|
||||||
throw NotFoundException.getNotFoundInstance();
|
}
|
||||||
|
|
||||||
|
private boolean isEndCharacter() {
|
||||||
|
return decodeRowResult.length() > 1 &&
|
||||||
|
arrayContains(STARTEND_ENCODING, ALPHABET[decodeRowResult.charAt(decodeRowResult.length() - 1)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateTrailingWhitespace(int nextStart) throws NotFoundException {
|
||||||
|
int trailingWhitespace = counters[nextStart - 1];
|
||||||
|
int lastPatternSize = calculateLastPatternSize(nextStart);
|
||||||
|
if (nextStart < counterLength && trailingWhitespace < lastPatternSize / 2) {
|
||||||
|
throw NotFoundException.getNotFoundInstance();
|
||||||
}
|
}
|
||||||
// Hack: We store the position in the alphabet table into a
|
}
|
||||||
// StringBuilder, so that we can access the decoded patterns in
|
|
||||||
// validatePattern. We'll translate to the actual characters later.
|
private int calculateLastPatternSize(int nextStart) {
|
||||||
decodeRowResult.append((char) charOffset);
|
int lastPatternSize = 0;
|
||||||
nextStart += 8;
|
for (int i = -8; i < -1; i++) {
|
||||||
// Stop as soon as we see the end character.
|
lastPatternSize += counters[nextStart + i];
|
||||||
if (decodeRowResult.length() > 1 &&
|
|
||||||
arrayContains(STARTEND_ENCODING, ALPHABET[charOffset])) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} while (nextStart < counterLength); // no fixed end pattern so keep on reading while data is available
|
return lastPatternSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void translateOffsetsToCharacters() {
|
||||||
|
for (int i = 0; i < decodeRowResult.length(); i++) {
|
||||||
|
decodeRowResult.setCharAt(i, ALPHABET[decodeRowResult.charAt(i)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Look for whitespace after pattern:
|
private void validateStartEndCharacters() throws NotFoundException {
|
||||||
int trailingWhitespace = counters[nextStart - 1];
|
char startChar = decodeRowResult.charAt(0);
|
||||||
int lastPatternSize = 0;
|
if (!arrayContains(STARTEND_ENCODING, startChar)) {
|
||||||
for (int i = -8; i < -1; i++) {
|
throw NotFoundException.getNotFoundInstance();
|
||||||
lastPatternSize += counters[nextStart + i];
|
}
|
||||||
}
|
char endChar = decodeRowResult.charAt(decodeRowResult.length() - 1);
|
||||||
|
if (!arrayContains(STARTEND_ENCODING, endChar)) {
|
||||||
|
throw NotFoundException.getNotFoundInstance();
|
||||||
|
}
|
||||||
|
if (decodeRowResult.length() <= MIN_CHARACTER_LENGTH) {
|
||||||
|
throw NotFoundException.getNotFoundInstance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We need to see whitespace equal to 50% of the last pattern size,
|
private void removeStartEndCharactersIfNeeded(Map<DecodeHintType, ?> hints) {
|
||||||
// otherwise this is probably a false positive. The exception is if we are
|
if (hints == null || !hints.containsKey(DecodeHintType.RETURN_CODABAR_START_END)) {
|
||||||
// at the end of the row. (I.e. the barcode barely fits.)
|
decodeRowResult.deleteCharAt(decodeRowResult.length() - 1);
|
||||||
if (nextStart < counterLength && trailingWhitespace < lastPatternSize / 2) {
|
decodeRowResult.deleteCharAt(0);
|
||||||
throw NotFoundException.getNotFoundInstance();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
validatePattern(startOffset);
|
|
||||||
|
|
||||||
// Translate character table offsets to actual characters.
|
|
||||||
for (int i = 0; i < decodeRowResult.length(); i++) {
|
|
||||||
decodeRowResult.setCharAt(i, ALPHABET[decodeRowResult.charAt(i)]);
|
|
||||||
}
|
|
||||||
// Ensure a valid start and end character
|
|
||||||
char startchar = decodeRowResult.charAt(0);
|
|
||||||
if (!arrayContains(STARTEND_ENCODING, startchar)) {
|
|
||||||
throw NotFoundException.getNotFoundInstance();
|
|
||||||
}
|
|
||||||
char endchar = decodeRowResult.charAt(decodeRowResult.length() - 1);
|
|
||||||
if (!arrayContains(STARTEND_ENCODING, endchar)) {
|
|
||||||
throw NotFoundException.getNotFoundInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove stop/start characters character and check if a long enough string is contained
|
|
||||||
if (decodeRowResult.length() <= MIN_CHARACTER_LENGTH) {
|
|
||||||
// Almost surely a false positive ( start + stop + at least 1 character)
|
|
||||||
throw NotFoundException.getNotFoundInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hints == null || !hints.containsKey(DecodeHintType.RETURN_CODABAR_START_END)) {
|
|
||||||
decodeRowResult.deleteCharAt(decodeRowResult.length() - 1);
|
|
||||||
decodeRowResult.deleteCharAt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private float[] calculateResultPositions(int startOffset, int nextStart) {
|
||||||
int runningCount = 0;
|
int runningCount = 0;
|
||||||
for (int i = 0; i < startOffset; i++) {
|
for (int i = 0; i < startOffset; i++) {
|
||||||
runningCount += counters[i];
|
runningCount += counters[i];
|
||||||
}
|
}
|
||||||
float left = runningCount;
|
float left = runningCount;
|
||||||
for (int i = startOffset; i < nextStart - 1; i++) {
|
for (int i = startOffset; i < nextStart - 1; i++) {
|
||||||
runningCount += counters[i];
|
runningCount += counters[i];
|
||||||
}
|
}
|
||||||
float right = runningCount;
|
float right = runningCount;
|
||||||
|
return new float[]{left, right};
|
||||||
Result result = new Result(
|
|
||||||
decodeRowResult.toString(),
|
|
||||||
null,
|
|
||||||
new ResultPoint[]{
|
|
||||||
new ResultPoint(left, rowNumber),
|
|
||||||
new ResultPoint(right, rowNumber)},
|
|
||||||
BarcodeFormat.CODABAR);
|
|
||||||
result.putMetadata(ResultMetadataType.SYMBOLOGY_IDENTIFIER, "]F0");
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Result buildResult(int rowNumber, float[] positions) {
|
||||||
|
return new Result(
|
||||||
|
decodeRowResult.toString(),
|
||||||
|
null,
|
||||||
|
new ResultPoint[]{
|
||||||
|
new ResultPoint(positions[0], rowNumber),
|
||||||
|
new ResultPoint(positions[1], rowNumber)
|
||||||
|
},
|
||||||
|
BarcodeFormat.CODABAR
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void validatePattern(int start) throws NotFoundException {
|
private void validatePattern(int start) throws NotFoundException {
|
||||||
// First, sum up the total size of our four categories of stripe sizes;
|
// First, sum up the total size of our four categories of stripe sizes;
|
||||||
int[] sizes = {0, 0, 0, 0};
|
int[] sizes = {0, 0, 0, 0};
|
||||||
|
|
Loading…
Reference in a new issue