findCornerFromCenter method

ResultPoint findCornerFromCenter(
  1. int centerX,
  2. int deltaX,
  3. int left,
  4. int right,
  5. int centerY,
  6. int deltaY,
  7. int top,
  8. int bottom,
  9. int maxWhiteRun,
)

Attempts to locate a corner of the barcode by scanning up, down, left or right from a center point which should be within the barcode.

@param centerX center's x component (horizontal) @param deltaX same as deltaY but change in x per step instead @param left minimum value of x @param right maximum value of x @param centerY center's y component (vertical) @param deltaY change in y per step. If scanning up this is negative; down, positive; left or right, 0 @param top minimum value of y to search through (meaningless when di == 0) @param bottom maximum value of y @param maxWhiteRun maximum run of white pixels that can still be considered to be within the barcode @return a ResultPoint encapsulating the corner that was found @throws NotFoundException if such a point cannot be found

Implementation

ResultPoint findCornerFromCenter(
  int centerX,
  int deltaX,
  int left,
  int right,
  int centerY,
  int deltaY,
  int top,
  int bottom,
  int maxWhiteRun,
) {
  List<int>? lastRange;
  for (int y = centerY, x = centerX;
      y < bottom && y >= top && x < right && x >= left;
      y += deltaY, x += deltaX) {
    List<int>? range;
    if (deltaX == 0) {
      // horizontal slices, up and down
      range = blackWhiteRange(y, maxWhiteRun, left, right, true);
    } else {
      // vertical slices, left and right
      range = blackWhiteRange(x, maxWhiteRun, top, bottom, false);
    }
    if (range == null) {
      if (lastRange == null) {
        throw NotFoundException.instance;
      }
      // lastRange was found
      if (deltaX == 0) {
        final lastY = y - deltaY;
        if (lastRange[0] < centerX) {
          if (lastRange[1] > centerX) {
            // straddle, choose one or the other based on direction
            return ResultPoint(
              lastRange[deltaY > 0 ? 0 : 1].toDouble(),
              lastY.toDouble(),
            );
          }
          return ResultPoint(lastRange[0].toDouble(), lastY.toDouble());
        } else {
          return ResultPoint(lastRange[1].toDouble(), lastY.toDouble());
        }
      } else {
        final lastX = x - deltaX;
        if (lastRange[0] < centerY) {
          if (lastRange[1] > centerY) {
            return ResultPoint(
              lastX.toDouble(),
              lastRange[deltaX < 0 ? 0 : 1].toDouble(),
            );
          }
          return ResultPoint(lastX.toDouble(), lastRange[0].toDouble());
        } else {
          return ResultPoint(lastX.toDouble(), lastRange[1].toDouble());
        }
      }
    }
    lastRange = range;
  }
  throw NotFoundException.instance;
}