int32_t
CBC_DetectionResultRowIndicatorColumn::adjustCompleteIndicatorColumnRowNumbers(
    CBC_BarcodeMetadata barcodeMetadata) {
  CFX_PtrArray* codewords = getCodewords();
  setRowNumbers();
  removeIncorrectCodewords(codewords, barcodeMetadata);
  CBC_BoundingBox* boundingBox = getBoundingBox();
  CBC_ResultPoint* top =
      m_isLeft ? boundingBox->getTopLeft() : boundingBox->getTopRight();
  CBC_ResultPoint* bottom =
      m_isLeft ? boundingBox->getBottomLeft() : boundingBox->getBottomRight();
  int32_t firstRow = imageRowToCodewordIndex((int32_t)top->GetY());
  int32_t lastRow = imageRowToCodewordIndex((int32_t)bottom->GetY());
  FX_FLOAT averageRowHeight =
      (lastRow - firstRow) / (FX_FLOAT)barcodeMetadata.getRowCount();
  int32_t barcodeRow = -1;
  int32_t maxRowHeight = 1;
  int32_t currentRowHeight = 0;
  for (int32_t codewordsRow = firstRow; codewordsRow < lastRow;
       codewordsRow++) {
    if (codewords->GetAt(codewordsRow) == NULL) {
      continue;
    }
    CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow);
    int32_t rowDifference = codeword->getRowNumber() - barcodeRow;
    if (rowDifference == 0) {
      currentRowHeight++;
    } else if (rowDifference == 1) {
      maxRowHeight =
          maxRowHeight > currentRowHeight ? maxRowHeight : currentRowHeight;
      currentRowHeight = 1;
      barcodeRow = codeword->getRowNumber();
    } else if (rowDifference < 0) {
      codewords->SetAt(codewordsRow, NULL);
    } else if (codeword->getRowNumber() >= barcodeMetadata.getRowCount()) {
      codewords->SetAt(codewordsRow, NULL);
    } else if (rowDifference > codewordsRow) {
      codewords->SetAt(codewordsRow, NULL);
    } else {
      int32_t checkedRows;
      if (maxRowHeight > 2) {
        checkedRows = (maxRowHeight - 2) * rowDifference;
      } else {
        checkedRows = rowDifference;
      }
      FX_BOOL closePreviousCodewordFound = checkedRows >= codewordsRow;
      for (int32_t i = 1; i <= checkedRows && !closePreviousCodewordFound;
           i++) {
        closePreviousCodewordFound = codewords->GetAt(codewordsRow - i) != NULL;
      }
      if (closePreviousCodewordFound) {
        codewords->SetAt(codewordsRow, NULL);
      } else {
        barcodeRow = codeword->getRowNumber();
        currentRowHeight = 1;
      }
    }
  }
  return (int32_t)(averageRowHeight + 0.5);
}
int32_t CBC_DetectionResultRowIndicatorColumn::
    adjustIncompleteIndicatorColumnRowNumbers(
        CBC_BarcodeMetadata barcodeMetadata) {
  CBC_BoundingBox* boundingBox = getBoundingBox();
  CBC_ResultPoint* top =
      m_isLeft ? boundingBox->getTopLeft() : boundingBox->getTopRight();
  CBC_ResultPoint* bottom =
      m_isLeft ? boundingBox->getBottomLeft() : boundingBox->getBottomRight();
  int32_t firstRow = imageRowToCodewordIndex((int32_t)top->GetY());
  int32_t lastRow = imageRowToCodewordIndex((int32_t)bottom->GetY());
  FX_FLOAT averageRowHeight =
      (lastRow - firstRow) / (FX_FLOAT)barcodeMetadata.getRowCount();
  CFX_PtrArray* codewords = getCodewords();
  int32_t barcodeRow = -1;
  int32_t maxRowHeight = 1;
  int32_t currentRowHeight = 0;
  for (int32_t codewordsRow = firstRow; codewordsRow < lastRow;
       codewordsRow++) {
    if (codewords->GetAt(codewordsRow) == NULL) {
      continue;
    }
    CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow);
    codeword->setRowNumberAsRowIndicatorColumn();
    int32_t rowDifference = codeword->getRowNumber() - barcodeRow;
    if (rowDifference == 0) {
      currentRowHeight++;
    } else if (rowDifference == 1) {
      maxRowHeight =
          maxRowHeight > currentRowHeight ? maxRowHeight : currentRowHeight;
      currentRowHeight = 1;
      barcodeRow = codeword->getRowNumber();
    } else if (codeword->getRowNumber() >= barcodeMetadata.getRowCount()) {
      codewords->SetAt(codewordsRow, NULL);
    } else {
      barcodeRow = codeword->getRowNumber();
      currentRowHeight = 1;
    }
  }
  return (int32_t)(averageRowHeight + 0.5);
}
Exemple #3
0
CFX_PtrArray* CBC_Detector::findRowsWithPattern(CBC_CommonBitMatrix* matrix,
                                                int32_t height,
                                                int32_t width,
                                                int32_t startRow,
                                                int32_t startColumn,
                                                int32_t* pattern,
                                                int32_t patternLength) {
  CFX_PtrArray* result = new CFX_PtrArray;
  result->SetSize(4);
  FX_BOOL found = FALSE;
  CFX_Int32Array counters;
  counters.SetSize(patternLength);
  for (; startRow < height; startRow += ROW_STEP) {
    CFX_Int32Array* loc =
        findGuardPattern(matrix, startColumn, startRow, width, FALSE, pattern,
                         patternLength, counters);
    if (loc != NULL) {
      while (startRow > 0) {
        CFX_Int32Array* previousRowLoc =
            findGuardPattern(matrix, startColumn, --startRow, width, FALSE,
                             pattern, patternLength, counters);
        if (previousRowLoc != NULL) {
          delete loc;
          loc = previousRowLoc;
        } else {
          startRow++;
          break;
        }
      }
      result->SetAt(
          0, new CBC_ResultPoint((FX_FLOAT)loc->GetAt(0), (FX_FLOAT)startRow));
      result->SetAt(
          1, new CBC_ResultPoint((FX_FLOAT)loc->GetAt(1), (FX_FLOAT)startRow));
      found = TRUE;
      delete loc;
      break;
    }
  }
  int32_t stopRow = startRow + 1;
  if (found) {
    int32_t skippedRowCount = 0;
    CFX_Int32Array previousRowLoc;
    previousRowLoc.Add((int32_t)((CBC_ResultPoint*)result->GetAt(0))->GetX());
    previousRowLoc.Add((int32_t)((CBC_ResultPoint*)result->GetAt(1))->GetX());
    for (; stopRow < height; stopRow++) {
      CFX_Int32Array* loc =
          findGuardPattern(matrix, previousRowLoc[0], stopRow, width, FALSE,
                           pattern, patternLength, counters);
      if (loc != NULL &&
          abs(previousRowLoc[0] - loc->GetAt(0)) < MAX_PATTERN_DRIFT &&
          abs(previousRowLoc[1] - loc->GetAt(1)) < MAX_PATTERN_DRIFT) {
        previousRowLoc.Copy(*loc);
        skippedRowCount = 0;
      } else {
        if (skippedRowCount > SKIPPED_ROW_COUNT_MAX) {
          delete loc;
          break;
        } else {
          skippedRowCount++;
        }
      }
      delete loc;
    }
    stopRow -= skippedRowCount + 1;
    result->SetAt(2, new CBC_ResultPoint((FX_FLOAT)previousRowLoc.GetAt(0),
                                         (FX_FLOAT)stopRow));
    result->SetAt(3, new CBC_ResultPoint((FX_FLOAT)previousRowLoc.GetAt(1),
                                         (FX_FLOAT)stopRow));
  }
  if (stopRow - startRow < BARCODE_MIN_HEIGHT) {
    for (int32_t i = 0; i < result->GetSize(); i++) {
      result->SetAt(i, NULL);
    }
  }
  return result;
}