find method

This method attempts to find the bottom-right alignment pattern in the image. It is a bit messy since it's pretty performance-critical and so is written to be fast foremost.

@return AlignmentPattern if found @throws NotFoundException if not found

Implementation

AlignmentPattern find() {
  final startX = _startX;
  final height = _height;
  final maxJ = startX + _width;
  final middleI = _startY + (height ~/ 2);
  // We are looking for black/white/black modules in 1:1:1 ratio;
  // this tracks the number of black/white/black modules seen so far
  final stateCount = [0, 0, 0];
  for (int iGen = 0; iGen < height; iGen++) {
    // Search from middle outwards
    final i =
        middleI + ((iGen & 0x01) == 0 ? (iGen + 1) ~/ 2 : -((iGen + 1) ~/ 2));
    stateCount[0] = 0;
    stateCount[1] = 0;
    stateCount[2] = 0;
    int j = startX;
    // Burn off leading white pixels before anything else; if we start in the middle of
    // a white run, it doesn't make sense to count its length, since we don't know if the
    // white run continued to the left of the start point
    while (j < maxJ && !_image.get(j, i)) {
      j++;
    }
    int currentState = 0;
    while (j < maxJ) {
      if (_image.get(j, i)) {
        // Black pixel
        if (currentState == 1) {
          // Counting black pixels
          stateCount[1]++;
        } else {
          // Counting white pixels
          if (currentState == 2) {
            // A winner?
            if (_foundPatternCross(stateCount)) {
              // Yes
              final confirmed = _handlePossibleCenter(stateCount, i, j);
              if (confirmed != null) {
                return confirmed;
              }
            }
            stateCount[0] = stateCount[2];
            stateCount[1] = 1;
            stateCount[2] = 0;
            currentState = 1;
          } else {
            stateCount[++currentState]++;
          }
        }
      } else {
        // White pixel
        if (currentState == 1) {
          // Counting black pixels
          currentState++;
        }
        stateCount[currentState]++;
      }
      j++;
    }
    if (_foundPatternCross(stateCount)) {
      final confirmed = _handlePossibleCenter(stateCount, i, maxJ);
      if (confirmed != null) {
        return confirmed;
      }
    }
  }

  // Hmm, nothing we saw was observed and confirmed twice. If we had
  // any guess at all, return it.
  if (_possibleCenters.isNotEmpty) {
    return _possibleCenters[0];
  }

  throw NotFoundException.instance;
}