Exemple #1
0
CFX_PtrArray* CBC_Detector::findVertices(CBC_CommonBitMatrix* matrix,
                                         int32_t startRow,
                                         int32_t startColumn) {
  int32_t height = matrix->GetHeight();
  int32_t width = matrix->GetWidth();
  CFX_PtrArray* result = new CFX_PtrArray;
  result->SetSize(8);
  CFX_PtrArray* startptr = findRowsWithPattern(
      matrix, height, width, startRow, startColumn, START_PATTERN,
      sizeof(START_PATTERN) / sizeof(START_PATTERN[0]));
  copyToResult(
      result, startptr, INDEXES_START_PATTERN,
      sizeof(INDEXES_START_PATTERN) / sizeof(INDEXES_START_PATTERN[0]));
  startptr->RemoveAll();
  delete startptr;
  if (result->GetAt(4) != NULL) {
    startColumn = (int32_t)((CBC_ResultPoint*)result->GetAt(4))->GetX();
    startRow = (int32_t)((CBC_ResultPoint*)result->GetAt(4))->GetY();
  }
  CFX_PtrArray* stopptr = findRowsWithPattern(
      matrix, height, width, startRow, startColumn, STOP_PATTERN,
      sizeof(STOP_PATTERN) / sizeof(STOP_PATTERN[0]));
  copyToResult(result, stopptr, INDEXES_STOP_PATTERN,
               sizeof(INDEXES_STOP_PATTERN) / sizeof(INDEXES_STOP_PATTERN[0]));
  stopptr->RemoveAll();
  delete stopptr;
  return result;
}
void CBC_DetectionResult::adjustRowNumbers(int32_t barcodeColumn,
                                           int32_t codewordsRow,
                                           CFX_PtrArray* codewords) {
  CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow);
  CFX_PtrArray* previousColumnCodewords =
      ((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(
           barcodeColumn - 1))
          ->getCodewords();
  CFX_PtrArray* nextColumnCodewords = previousColumnCodewords;
  if (m_detectionResultColumns[barcodeColumn + 1]) {
    nextColumnCodewords = ((CBC_DetectionResultColumn*)
                               m_detectionResultColumns[barcodeColumn + 1])
                              ->getCodewords();
  }
  CFX_PtrArray otherCodewords;
  otherCodewords.SetSize(14);
  otherCodewords[2] = previousColumnCodewords->GetAt(codewordsRow);
  otherCodewords[3] = nextColumnCodewords->GetAt(codewordsRow);
  if (codewordsRow > 0) {
    otherCodewords[0] = codewords->GetAt(codewordsRow - 1);
    otherCodewords[4] = previousColumnCodewords->GetAt(codewordsRow - 1);
    otherCodewords[5] = nextColumnCodewords->GetAt(codewordsRow - 1);
  }
  if (codewordsRow > 1) {
    otherCodewords[8] = codewords->GetAt(codewordsRow - 2);
    otherCodewords[10] = previousColumnCodewords->GetAt(codewordsRow - 2);
    otherCodewords[11] = nextColumnCodewords->GetAt(codewordsRow - 2);
  }
  if (codewordsRow < codewords->GetSize() - 1) {
    otherCodewords[1] = codewords->GetAt(codewordsRow + 1);
    otherCodewords[6] = previousColumnCodewords->GetAt(codewordsRow + 1);
    otherCodewords[7] = nextColumnCodewords->GetAt(codewordsRow + 1);
  }
  if (codewordsRow < codewords->GetSize() - 2) {
    otherCodewords[9] = codewords->GetAt(codewordsRow + 2);
    otherCodewords[12] = previousColumnCodewords->GetAt(codewordsRow + 2);
    otherCodewords[13] = nextColumnCodewords->GetAt(codewordsRow + 2);
  }
  for (int32_t i = 0; i < otherCodewords.GetSize(); i++) {
    CBC_Codeword* otherCodeword = (CBC_Codeword*)otherCodewords.GetAt(i);
    if (adjustRowNumber(codeword, otherCodeword)) {
      return;
    }
  }
}
Exemple #3
0
CFX_PtrArray* CBC_QRDataBlock::GetDataBlocks(
    CFX_ByteArray* rawCodewords,
    CBC_QRCoderVersion* version,
    CBC_QRCoderErrorCorrectionLevel* ecLevel,
    int32_t& e) {
  if (rawCodewords->GetSize() != version->GetTotalCodeWords()) {
    e = BCExceptionIllegalArgument;
    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  }
  CBC_QRCoderECBlocks* ecBlocks = version->GetECBlocksForLevel(ecLevel);
  int32_t totalBlocks = 0;
  CFX_PtrArray* ecBlockArray = ecBlocks->GetECBlocks();
  int32_t i = 0;
  for (i = 0; i < ecBlockArray->GetSize(); i++) {
    totalBlocks += ((CBC_QRCoderECB*)(*ecBlockArray)[i])->GetCount();
  }
  CFX_PtrArray* datablock = new CFX_PtrArray();
  datablock->SetSize(totalBlocks);
  CBC_AutoPtr<CFX_PtrArray> result(datablock);
  int32_t numResultBlocks = 0;
  for (int32_t j = 0; j < ecBlockArray->GetSize(); j++) {
    CBC_QRCoderECB* ecBlock = (CBC_QRCoderECB*)(*ecBlockArray)[j];
    for (int32_t k = 0; k < ecBlock->GetCount(); k++) {
      int32_t numDataCodewords = ecBlock->GetDataCodeWords();
      int32_t numBlockCodewords =
          ecBlocks->GetECCodeWordsPerBlock() + numDataCodewords;
      CFX_ByteArray* bytearray = new CFX_ByteArray();
      bytearray->SetSize(numBlockCodewords);
      (*result)[numResultBlocks++] =
          new CBC_QRDataBlock(numDataCodewords, bytearray);
    }
  }
  int32_t shorterBlocksTotalCodewords =
      ((CBC_QRDataBlock*)(*result)[0])->m_codewords->GetSize();
  int32_t longerBlocksStartAt = result->GetSize() - 1;
  while (longerBlocksStartAt >= 0) {
    int32_t numCodewords = ((CBC_QRDataBlock*)(*result)[longerBlocksStartAt])
                               ->m_codewords->GetSize();
    if (numCodewords == shorterBlocksTotalCodewords) {
      break;
    }
    longerBlocksStartAt--;
  }
  longerBlocksStartAt++;
  int32_t shorterBlocksNumDataCodewords =
      shorterBlocksTotalCodewords - ecBlocks->GetECCodeWordsPerBlock();
  int32_t rawCodewordsOffset = 0;
  int32_t x = 0;
  for (int32_t k = 0; k < shorterBlocksNumDataCodewords; k++) {
    for (x = 0; x < numResultBlocks; x++) {
      (*(((CBC_QRDataBlock*)(*result)[x])->m_codewords))[k] =
          (*rawCodewords)[rawCodewordsOffset++];
    }
  }
  for (x = longerBlocksStartAt; x < numResultBlocks; x++) {
    (*(((CBC_QRDataBlock*)(*result)[x])
           ->m_codewords))[shorterBlocksNumDataCodewords] =
        (*rawCodewords)[rawCodewordsOffset++];
  }
  int32_t max = ((CBC_QRDataBlock*)(*result)[0])->m_codewords->GetSize();
  for (i = shorterBlocksNumDataCodewords; i < max; i++) {
    for (int32_t y = 0; y < numResultBlocks; y++) {
      int32_t iOffset = y < longerBlocksStartAt ? i : i + 1;
      (*(((CBC_QRDataBlock*)(*result)[y])->m_codewords))[iOffset] =
          (*rawCodewords)[rawCodewordsOffset++];
    }
  }
  return result.release();
}
Exemple #4
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;
}
CBC_QRDetectorResult* CBC_DataMatrixDetector::Detect(int32_t& e) {
  CFX_PtrArray* cornerPoints = m_rectangleDetector->Detect(e);
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  CBC_ResultPoint* pointA = (CBC_ResultPoint*)(*cornerPoints)[0];
  CBC_ResultPoint* pointB = (CBC_ResultPoint*)(*cornerPoints)[1];
  CBC_ResultPoint* pointC = (CBC_ResultPoint*)(*cornerPoints)[2];
  CBC_ResultPoint* pointD = (CBC_ResultPoint*)(*cornerPoints)[3];
  delete cornerPoints;
  cornerPoints = NULL;
  CFX_PtrArray transitions;
  transitions.Add(TransitionsBetween(pointA, pointB));
  transitions.Add(TransitionsBetween(pointA, pointC));
  transitions.Add(TransitionsBetween(pointB, pointD));
  transitions.Add(TransitionsBetween(pointC, pointD));
  BC_FX_PtrArray_Sort(transitions, &ResultPointsAndTransitionsComparator);
  delete ((CBC_ResultPointsAndTransitions*)transitions[2]);
  delete ((CBC_ResultPointsAndTransitions*)transitions[3]);
  CBC_ResultPointsAndTransitions* lSideOne =
      (CBC_ResultPointsAndTransitions*)transitions[0];
  CBC_ResultPointsAndTransitions* lSideTwo =
      (CBC_ResultPointsAndTransitions*)transitions[1];
  CFX_MapPtrTemplate<CBC_ResultPoint*, int32_t> pointCount;
  Increment(pointCount, lSideOne->GetFrom());
  Increment(pointCount, lSideOne->GetTo());
  Increment(pointCount, lSideTwo->GetFrom());
  Increment(pointCount, lSideTwo->GetTo());
  delete ((CBC_ResultPointsAndTransitions*)transitions[1]);
  delete ((CBC_ResultPointsAndTransitions*)transitions[0]);
  transitions.RemoveAll();
  CBC_ResultPoint* maybeTopLeft = NULL;
  CBC_ResultPoint* bottomLeft = NULL;
  CBC_ResultPoint* maybeBottomRight = NULL;
  FX_POSITION itBegin = pointCount.GetStartPosition();
  while (itBegin != NULL) {
    CBC_ResultPoint* key = 0;
    int32_t value = 0;
    pointCount.GetNextAssoc(itBegin, key, value);
    if (value == 2) {
      bottomLeft = key;
    } else {
      if (maybeBottomRight == NULL) {
        maybeBottomRight = key;
      } else {
        maybeTopLeft = key;
      }
    }
  }
  if (maybeTopLeft == NULL || bottomLeft == NULL || maybeBottomRight == NULL) {
    delete pointA;
    delete pointB;
    delete pointC;
    delete pointD;
    e = BCExceptionNotFound;
    return NULL;
  }
  CFX_PtrArray corners;
  corners.SetSize(3);
  corners[0] = maybeTopLeft;
  corners[1] = bottomLeft;
  corners[2] = maybeBottomRight;
  OrderBestPatterns(&corners);
  CBC_ResultPoint* bottomRight = (CBC_ResultPoint*)corners[0];
  bottomLeft = (CBC_ResultPoint*)corners[1];
  CBC_ResultPoint* topLeft = (CBC_ResultPoint*)corners[2];
  CBC_ResultPoint* topRight = NULL;
  int32_t value;
  if (!pointCount.Lookup(pointA, value)) {
    topRight = pointA;
  } else if (!pointCount.Lookup(pointB, value)) {
    topRight = pointB;
  } else if (!pointCount.Lookup(pointC, value)) {
    topRight = pointC;
  } else {
    topRight = pointD;
  }
  int32_t dimensionTop = CBC_AutoPtr<CBC_ResultPointsAndTransitions>(
                             TransitionsBetween(topLeft, topRight))
                             ->GetTransitions();
  int32_t dimensionRight = CBC_AutoPtr<CBC_ResultPointsAndTransitions>(
                               TransitionsBetween(bottomRight, topRight))
                               ->GetTransitions();
  if ((dimensionTop & 0x01) == 1) {
    dimensionTop++;
  }
  dimensionTop += 2;
  if ((dimensionRight & 0x01) == 1) {
    dimensionRight++;
  }
  dimensionRight += 2;
  CBC_AutoPtr<CBC_CommonBitMatrix> bits(NULL);
  CBC_AutoPtr<CBC_ResultPoint> correctedTopRight(NULL);
  if (4 * dimensionTop >= 7 * dimensionRight ||
      4 * dimensionRight >= 7 * dimensionTop) {
    correctedTopRight = CBC_AutoPtr<CBC_ResultPoint>(
        CorrectTopRightRectangular(bottomLeft, bottomRight, topLeft, topRight,
                                   dimensionTop, dimensionRight));
    if (correctedTopRight.get() == NULL) {
      correctedTopRight = CBC_AutoPtr<CBC_ResultPoint>(topRight);
    } else {
      delete topRight;
      topRight = NULL;
    }
    dimensionTop = CBC_AutoPtr<CBC_ResultPointsAndTransitions>(
                       TransitionsBetween(topLeft, correctedTopRight.get()))
                       ->GetTransitions();
    dimensionRight =
        CBC_AutoPtr<CBC_ResultPointsAndTransitions>(
            TransitionsBetween(bottomRight, correctedTopRight.get()))
            ->GetTransitions();
    if ((dimensionTop & 0x01) == 1) {
      dimensionTop++;
    }
    if ((dimensionRight & 0x01) == 1) {
      dimensionRight++;
    }
    bits = CBC_AutoPtr<CBC_CommonBitMatrix>(
        SampleGrid(m_image, topLeft, bottomLeft, bottomRight,
                   correctedTopRight.get(), dimensionTop, dimensionRight, e));
    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  } else {
    int32_t dimension = std::min(dimensionRight, dimensionTop);
    correctedTopRight = CBC_AutoPtr<CBC_ResultPoint>(
        CorrectTopRight(bottomLeft, bottomRight, topLeft, topRight, dimension));
    if (correctedTopRight.get() == NULL) {
      correctedTopRight = CBC_AutoPtr<CBC_ResultPoint>(topRight);
    } else {
      delete topRight;
      topRight = NULL;
    }
    int32_t dimensionCorrected =
        std::max(CBC_AutoPtr<CBC_ResultPointsAndTransitions>(
                     TransitionsBetween(topLeft, correctedTopRight.get()))
                     ->GetTransitions(),
                 CBC_AutoPtr<CBC_ResultPointsAndTransitions>(
                     TransitionsBetween(bottomRight, correctedTopRight.get()))
                     ->GetTransitions());
    dimensionCorrected++;
    if ((dimensionCorrected & 0x01) == 1) {
      dimensionCorrected++;
    }
    bits = CBC_AutoPtr<CBC_CommonBitMatrix>(SampleGrid(
        m_image, topLeft, bottomLeft, bottomRight, correctedTopRight.get(),
        dimensionCorrected, dimensionCorrected, e));
    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  }
  CFX_PtrArray* result = new CFX_PtrArray;
  result->SetSize(4);
  result->Add(topLeft);
  result->Add(bottomLeft);
  result->Add(bottomRight);
  result->Add(correctedTopRight.release());
  return new CBC_QRDetectorResult(bits.release(), result);
}