CFX_Int32Array* CBC_PDF417CodewordDecoder::sampleBitCounts(
    CFX_Int32Array& moduleBitCount) {
  FX_FLOAT bitCountSum =
      (FX_FLOAT)CBC_PDF417Common::getBitCountSum(moduleBitCount);
  CFX_Int32Array* bitCount = new CFX_Int32Array();
  bitCount->SetSize(CBC_PDF417Common::BARS_IN_MODULE);
  int32_t bitCountIndex = 0;
  int32_t sumPreviousBits = 0;
  for (int32_t i = 0; i < CBC_PDF417Common::MODULES_IN_CODEWORD; i++) {
    FX_FLOAT sampleIndex =
        bitCountSum / (2 * CBC_PDF417Common::MODULES_IN_CODEWORD) +
        (i * bitCountSum) / CBC_PDF417Common::MODULES_IN_CODEWORD;
    if (sumPreviousBits + moduleBitCount.GetAt(bitCountIndex) <= sampleIndex) {
      sumPreviousBits += moduleBitCount.GetAt(bitCountIndex);
      bitCountIndex++;
    }
    bitCount->SetAt(bitCountIndex, bitCount->GetAt(bitCountIndex) + 1);
  }
  return bitCount;
}
void CBC_PDF417::generateBarcodeLogic(CFX_WideString msg,
                                      int32_t errorCorrectionLevel,
                                      int32_t& e) {
  int32_t errorCorrectionCodeWords =
      CBC_PDF417ErrorCorrection::getErrorCorrectionCodewordCount(
          errorCorrectionLevel, e);
  BC_EXCEPTION_CHECK_ReturnVoid(e);
  CFX_WideString highLevel =
      CBC_PDF417HighLevelEncoder::encodeHighLevel(msg, m_compaction, e);
  BC_EXCEPTION_CHECK_ReturnVoid(e);
  int32_t sourceCodeWords = highLevel.GetLength();
  CFX_Int32Array* dimension =
      determineDimensions(sourceCodeWords, errorCorrectionCodeWords, e);
  BC_EXCEPTION_CHECK_ReturnVoid(e);
  int32_t cols = dimension->GetAt(0);
  int32_t rows = dimension->GetAt(1);
  delete dimension;
  int32_t pad = getNumberOfPadCodewords(sourceCodeWords,
                                        errorCorrectionCodeWords, cols, rows);
  if (sourceCodeWords + errorCorrectionCodeWords + 1 > 929) {
    e = BCExceptionEncodedMessageContainsTooManyCodeWords;
    return;
  }
  int32_t n = sourceCodeWords + pad + 1;
  CFX_WideString sb;
  sb += (FX_WCHAR)n;
  sb += highLevel;
  for (int32_t i = 0; i < pad; i++) {
    sb += (FX_WCHAR)900;
  }
  CFX_WideString dataCodewords(sb);
  CFX_WideString ec = CBC_PDF417ErrorCorrection::generateErrorCorrection(
      dataCodewords, errorCorrectionLevel, e);
  BC_EXCEPTION_CHECK_ReturnVoid(e);
  CFX_WideString fullCodewords = dataCodewords + ec;
  m_barcodeMatrix = new CBC_BarcodeMatrix(rows, cols);
  encodeLowLevel(fullCodewords, cols, rows, errorCorrectionLevel,
                 m_barcodeMatrix);
}
int32_t CBC_PDF417CodewordDecoder::getClosestDecodedValue(
    CFX_Int32Array& moduleBitCount) {
  int32_t bitCountSum = CBC_PDF417Common::getBitCountSum(moduleBitCount);
  CFX_FloatArray bitCountRatios;
  bitCountRatios.SetSize(CBC_PDF417Common::BARS_IN_MODULE);
  for (int32_t i = 0; i < bitCountRatios.GetSize(); i++) {
    bitCountRatios[i] = moduleBitCount.GetAt(i) / (FX_FLOAT)bitCountSum;
  }
  FX_FLOAT bestMatchError = std::numeric_limits<int32_t>::max();
  int32_t bestMatch = -1;
  for (int32_t j = 0; j < SYMBOL_TABLE_Length; j++) {
    FX_FLOAT error = 0.0f;
    for (int32_t k = 0; k < CBC_PDF417Common::BARS_IN_MODULE; k++) {
      FX_FLOAT diff = RATIOS_TABLE[j][k] - bitCountRatios[k];
      error += diff * diff;
    }
    if (error < bestMatchError) {
      bestMatchError = error;
      bestMatch = CBC_PDF417Common::SYMBOL_TABLE[j];
    }
  }
  return bestMatch;
}
Beispiel #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;
}