void CBC_DetectionResultRowIndicatorColumn::setRowNumbers() {
  for (int32_t i = 0; i < m_codewords->GetSize(); i++) {
    CBC_Codeword* codeword = (CBC_Codeword*)m_codewords->GetAt(i);
    if (codeword != NULL) {
      codeword->setRowNumberAsRowIndicatorColumn();
    }
  }
}
CBC_BarcodeMetadata*
CBC_DetectionResultRowIndicatorColumn::getBarcodeMetadata() {
  CFX_PtrArray* codewords = getCodewords();
  CBC_BarcodeValue barcodeColumnCount;
  CBC_BarcodeValue barcodeRowCountUpperPart;
  CBC_BarcodeValue barcodeRowCountLowerPart;
  CBC_BarcodeValue barcodeECLevel;
  for (int32_t i = 0; i < codewords->GetSize(); i++) {
    CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(i);
    if (codeword == NULL) {
      continue;
    }
    codeword->setRowNumberAsRowIndicatorColumn();
    int32_t rowIndicatorValue = codeword->getValue() % 30;
    int32_t codewordRowNumber = codeword->getRowNumber();
    if (!m_isLeft) {
      codewordRowNumber += 2;
    }
    switch (codewordRowNumber % 3) {
      case 0:
        barcodeRowCountUpperPart.setValue(rowIndicatorValue * 3 + 1);
        break;
      case 1:
        barcodeECLevel.setValue(rowIndicatorValue / 3);
        barcodeRowCountLowerPart.setValue(rowIndicatorValue % 3);
        break;
      case 2:
        barcodeColumnCount.setValue(rowIndicatorValue + 1);
        break;
    }
  }
  if ((barcodeColumnCount.getValue()->GetSize() == 0) ||
      (barcodeRowCountUpperPart.getValue()->GetSize() == 0) ||
      (barcodeRowCountLowerPart.getValue()->GetSize() == 0) ||
      (barcodeECLevel.getValue()->GetSize() == 0) ||
      barcodeColumnCount.getValue()->GetAt(0) < 1 ||
      barcodeRowCountUpperPart.getValue()->GetAt(0) +
              barcodeRowCountLowerPart.getValue()->GetAt(0) <
          CBC_PDF417Common::MIN_ROWS_IN_BARCODE ||
      barcodeRowCountUpperPart.getValue()->GetAt(0) +
              barcodeRowCountLowerPart.getValue()->GetAt(0) >
          CBC_PDF417Common::MAX_ROWS_IN_BARCODE) {
    return NULL;
  }
  CBC_BarcodeMetadata* barcodeMetadata =
      new CBC_BarcodeMetadata(barcodeColumnCount.getValue()->GetAt(0),
                              barcodeRowCountUpperPart.getValue()->GetAt(0),
                              barcodeRowCountLowerPart.getValue()->GetAt(0),
                              barcodeECLevel.getValue()->GetAt(0));
  removeIncorrectCodewords(codewords, *barcodeMetadata);
  return barcodeMetadata;
}
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);
}