scan static method

List<UCode> scan(
  1. UBitMatrix matrix,
  2. UCodeScanOptions options
)

Implementation

static List<UCode> scan(UBitMatrix matrix, UCodeScanOptions options) {
  final Set<UCodeFormat> formats = options.effectiveFormats;
  final bool wantsUpcEan = formats.contains(UCodeFormat.ean13) ||
      formats.contains(UCodeFormat.ean8) ||
      formats.contains(UCodeFormat.upcA) ||
      formats.contains(UCodeFormat.upcE);
  if (!wantsUpcEan &&
      !formats.contains(UCodeFormat.code128) &&
      !formats.contains(UCodeFormat.code39) &&
      !formats.contains(UCodeFormat.code93) &&
      !formats.contains(UCodeFormat.codabar) &&
      !formats.contains(UCodeFormat.itf)) {
    return const <UCode>[];
  }

  final List<UCode> found = <UCode>[];
  final Set<String> seen = <String>{};
  final int height = matrix.height;
  final int middle = height ~/ 2;
  final int rowStep = max(1, height ~/ (options.tryHarder ? 40 : 16));

  for (int pass = 0; pass < (options.tryHarder ? 40 : 16); pass++) {
    final int rowStepsAboveOrBelow = (pass + 1) ~/ 2;
    final bool isAbove = pass.isEven;
    final int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
    if (rowNumber < 0 || rowNumber >= height) continue;

    final UBitArray row = UBitArray.fromMatrixRow(matrix, rowNumber);
    for (int attempt = 0; attempt < 2; attempt++) {
      final UBitArray candidate = attempt == 0 ? row : row.reversed();
      final List<U1DResult> results = _decodeRow(candidate, formats, wantsUpcEan);
      for (final U1DResult result in results) {
        final String key = "${result.format.name}:${result.text}";
        if (!seen.add(key)) continue;
        final double left = attempt == 0 ? result.start : matrix.width - result.end;
        final double right = attempt == 0 ? result.end : matrix.width - result.start;
        found.add(
          UCode(
            format: result.format,
            text: result.text,
            bytes: Uint8List.fromList(result.text.codeUnits),
            corners: <Offset>[
              Offset(left, rowNumber.toDouble()),
              Offset(right, rowNumber.toDouble()),
              Offset(right, rowNumber.toDouble()),
              Offset(left, rowNumber.toDouble()),
            ],
          ),
        );
        if (!options.multiple) return found;
      }
    }
  }
  return found;
}