Update CodaBarReader.java

This commit is contained in:
juanmz1606 2024-09-04 09:07:17 -05:00 committed by GitHub
parent 8944e60778
commit cefd502bb3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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};