decodeRow method
Attempts to decode a one-dimensional barcode format given a single row of an image.
@param rowNumber row number from top of the row @param row the black/white pixel data of the row @param hints decode hints @return Result containing encoded string and start/end of barcode @throws NotFoundException if no potential barcode is found @throws ChecksumException if a potential barcode is found but does not pass its checksum @throws FormatException if a potential barcode is found but format is invalid
Implementation
@override
Result decodeRow(
int rowNumber,
BitArray row,
DecodeHint? hints,
) {
final theCounters = _counters;
theCounters.fillRange(0, theCounters.length, 0);
final result = _decodeRowResult;
result.clear();
final start = _findAsteriskPattern(row, theCounters);
// Read off white space
int nextStart = row.getNextSet(start[1]);
final end = row.size;
String decodedChar;
int lastStart;
do {
OneDReader.recordPattern(row, nextStart, theCounters);
final pattern = _toNarrowWidePattern(theCounters);
if (pattern < 0) {
throw NotFoundException.instance;
}
decodedChar = _patternToChar(pattern);
result.write(decodedChar);
lastStart = nextStart;
for (int counter in theCounters) {
nextStart += counter;
}
// Read off white space
nextStart = row.getNextSet(nextStart);
} while (decodedChar != '*');
result.setLength(result.length - 1); // remove asterisk
// Look for whitespace after pattern:
int lastPatternSize = 0;
for (int counter in theCounters) {
lastPatternSize += counter;
}
final 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 NotFoundException.instance;
}
if (_usingCheckDigit) {
final max = result.length - 1;
int total = 0;
for (int i = 0; i < max; i++) {
total += alphabetString.indexOf(_decodeRowResult.charAt(i));
}
if (result.codePointAt(max) != alphabetString.codeUnitAt(total % 43)) {
throw ChecksumException.getChecksumInstance();
}
result.setLength(max);
}
if (result.length == 0) {
// false positive
throw NotFoundException.instance;
}
String resultString;
if (_extendedMode) {
resultString = _decodeExtended(result.toString());
} else {
resultString = result.toString();
}
final left = (start[1] + start[0]) / 2.0;
final right = lastStart + lastPatternSize / 2.0;
final resultObject = Result(
resultString,
null,
[
ResultPoint(left, rowNumber.toDouble()),
ResultPoint(right, rowNumber.toDouble())
],
BarcodeFormat.code39,
);
resultObject.putMetadata(ResultMetadataType.symbologyIdentifier, ']A0');
return resultObject;
}