decodeRow method

  1. @override
Result decodeRow(
  1. int rowNumber,
  2. BitArray row,
  3. DecodeHint? hints
)
override

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