decodeDataCharacter method

DataCharacter decodeDataCharacter(
  1. BitArray row,
  2. FinderPattern pattern,
  3. bool isOddPattern,
  4. bool leftChar,
)

Implementation

DataCharacter decodeDataCharacter(
  BitArray row,
  FinderPattern pattern,
  bool isOddPattern,
  bool leftChar,
) {
  final counters = dataCharacterCounters;
  counters.fillRange(0, counters.length, 0);

  if (leftChar) {
    OneDReader.recordPatternInReverse(row, pattern.startEnd[0], counters);
  } else {
    OneDReader.recordPattern(row, pattern.startEnd[1], counters);
    // reverse it
    for (int i = 0, j = counters.length - 1; i < j; i++, j--) {
      final temp = counters[i];
      counters[i] = counters[j];
      counters[j] = temp;
    }
  } //List<counters> has the pixels of the module

  //left and right data characters have all the same length
  final numModules = 17;
  final elementWidth = MathUtils.sum(counters) / numModules;

  // Sanity check: element width for pattern and the character should match
  final expectedElementWidth =
      (pattern.startEnd[1] - pattern.startEnd[0]) / 15.0;
  if ((elementWidth - expectedElementWidth).abs() / expectedElementWidth >
      0.3) {
    throw NotFoundException.instance;
  }

  // TODO is need?
  // List<int> oddCounts = this.oddCounts;
  // List<int> evenCounts = this.evenCounts;
  // List<double> oddRoundingErrors = this.oddRoundingErrors;
  // List<double> evenRoundingErrors = this.evenRoundingErrors;

  for (int i = 0; i < counters.length; i++) {
    final value = 1.0 * counters[i] / elementWidth;
    int count = (value + 0.5).toInt(); // Round
    if (count < 1) {
      if (value < 0.3) {
        throw NotFoundException.instance;
      }
      count = 1;
    } else if (count > 8) {
      if (value > 8.7) {
        throw NotFoundException.instance;
      }
      count = 8;
    }
    final offset = i ~/ 2;
    if ((i & 0x01) == 0) {
      oddCounts[offset] = count;
      oddRoundingErrors[offset] = value - count;
    } else {
      evenCounts[offset] = count;
      evenRoundingErrors[offset] = value - count;
    }
  }

  _adjustOddEvenCounts(numModules);

  final weightRowNumber =
      4 * pattern.value + (isOddPattern ? 0 : 2) + (leftChar ? 0 : 1) - 1;

  int oddSum = 0;
  int oddChecksumPortion = 0;
  for (int i = oddCounts.length - 1; i >= 0; i--) {
    if (_isNotA1left(pattern, isOddPattern, leftChar)) {
      final weight = _WEIGHTS[weightRowNumber][2 * i];
      oddChecksumPortion += oddCounts[i] * weight;
    }
    oddSum += oddCounts[i];
  }
  int evenChecksumPortion = 0;
  for (int i = evenCounts.length - 1; i >= 0; i--) {
    if (_isNotA1left(pattern, isOddPattern, leftChar)) {
      final weight = _WEIGHTS[weightRowNumber][2 * i + 1];
      evenChecksumPortion += evenCounts[i] * weight;
    }
  }
  final checksumPortion = oddChecksumPortion + evenChecksumPortion;

  if ((oddSum & 0x01) != 0 || oddSum > 13 || oddSum < 4) {
    throw NotFoundException.instance;
  }

  final group = (13 - oddSum) ~/ 2;
  final oddWidest = _SYMBOL_WIDEST[group];
  final evenWidest = 9 - oddWidest;
  final vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, true);
  final vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, false);
  final tEven = _EVEN_TOTAL_SUBSET[group];
  final gSum = _GSUM[group];
  final value = vOdd * tEven + vEven + gSum;

  return DataCharacter(value, checksumPortion);
}