int32_t CBC_DecodedBitStreamPaser::textCompaction(CFX_Int32Array& codewords,
                                                  int32_t codeIndex,
                                                  CFX_ByteString& result) {
  CFX_Int32Array textCompactionData;
  textCompactionData.SetSize((codewords[0] - codeIndex) << 1);
  CFX_Int32Array byteCompactionData;
  byteCompactionData.SetSize((codewords[0] - codeIndex) << 1);
  int32_t index = 0;
  FX_BOOL end = FALSE;
  while ((codeIndex < codewords[0]) && !end) {
    int32_t code = codewords[codeIndex++];
    if (code < TEXT_COMPACTION_MODE_LATCH) {
      textCompactionData[index] = code / 30;
      textCompactionData[index + 1] = code % 30;
      index += 2;
    } else {
      switch (code) {
        case TEXT_COMPACTION_MODE_LATCH:
          textCompactionData[index++] = TEXT_COMPACTION_MODE_LATCH;
          break;
        case BYTE_COMPACTION_MODE_LATCH:
          codeIndex--;
          end = TRUE;
          break;
        case NUMERIC_COMPACTION_MODE_LATCH:
          codeIndex--;
          end = TRUE;
          break;
        case BEGIN_MACRO_PDF417_CONTROL_BLOCK:
          codeIndex--;
          end = TRUE;
          break;
        case BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
          codeIndex--;
          end = TRUE;
          break;
        case MACRO_PDF417_TERMINATOR:
          codeIndex--;
          end = TRUE;
          break;
        case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
          textCompactionData[index] = MODE_SHIFT_TO_BYTE_COMPACTION_MODE;
          code = codewords[codeIndex++];
          byteCompactionData[index] = code;
          index++;
          break;
        case BYTE_COMPACTION_MODE_LATCH_6:
          codeIndex--;
          end = TRUE;
          break;
      }
    }
  }
  decodeTextCompaction(textCompactionData, byteCompactionData, index, result);
  return codeIndex;
}
int32_t CBC_DecodedBitStreamPaser::decodeMacroBlock(
    CFX_Int32Array& codewords,
    int32_t codeIndex,
    CBC_PDF417ResultMetadata* resultMetadata,
    int32_t& e) {
  if (codeIndex + NUMBER_OF_SEQUENCE_CODEWORDS > codewords[0]) {
    e = BCExceptionFormatInstance;
    return -1;
  }
  CFX_Int32Array segmentIndexArray;
  segmentIndexArray.SetSize(NUMBER_OF_SEQUENCE_CODEWORDS);
  for (int32_t i = 0; i < NUMBER_OF_SEQUENCE_CODEWORDS; i++, codeIndex++) {
    segmentIndexArray.SetAt(i, codewords[codeIndex]);
  }
  CFX_ByteString str =
      decodeBase900toBase10(segmentIndexArray, NUMBER_OF_SEQUENCE_CODEWORDS, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, -1);
  resultMetadata->setSegmentIndex(atoi(str.GetBuffer(str.GetLength())));
  CFX_ByteString fileId;
  codeIndex = textCompaction(codewords, codeIndex, fileId);
  resultMetadata->setFileId(fileId);
  if (codewords[codeIndex] == BEGIN_MACRO_PDF417_OPTIONAL_FIELD) {
    codeIndex++;
    CFX_Int32Array additionalOptionCodeWords;
    additionalOptionCodeWords.SetSize(codewords[0] - codeIndex);
    int32_t additionalOptionCodeWordsIndex = 0;
    FX_BOOL end = FALSE;
    while ((codeIndex < codewords[0]) && !end) {
      int32_t code = codewords[codeIndex++];
      if (code < TEXT_COMPACTION_MODE_LATCH) {
        additionalOptionCodeWords[additionalOptionCodeWordsIndex++] = code;
      } else {
        switch (code) {
          case MACRO_PDF417_TERMINATOR:
            resultMetadata->setLastSegment(TRUE);
            codeIndex++;
            end = TRUE;
            break;
          default:
            e = BCExceptionFormatInstance;
            return -1;
        }
      }
    }
    CFX_Int32Array array;
    array.SetSize(additionalOptionCodeWordsIndex);
    array.Copy(additionalOptionCodeWords);
    resultMetadata->setOptionalData(array);
  } else if (codewords[codeIndex] == MACRO_PDF417_TERMINATOR) {
    resultMetadata->setLastSegment(TRUE);
    codeIndex++;
  }
  return codeIndex;
}
CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Multiply(
    CBC_ReedSolomonGF256Poly* other,
    int32_t& e) {
  if (IsZero() || other->IsZero()) {
    CBC_ReedSolomonGF256Poly* temp = m_field->GetZero()->Clone(e);
    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
    return temp;
  }
  CFX_Int32Array aCoefficients;
  aCoefficients.Copy(m_coefficients);
  int32_t aLength = m_coefficients.GetSize();
  CFX_Int32Array bCoefficients;
  bCoefficients.Copy(*(other->GetCoefficients()));
  int32_t bLength = other->GetCoefficients()->GetSize();
  CFX_Int32Array product;
  product.SetSize(aLength + bLength - 1);
  for (int32_t i = 0; i < aLength; i++) {
    int32_t aCoeff = m_coefficients[i];
    for (int32_t j = 0; j < bLength; j++) {
      product[i + j] = CBC_ReedSolomonGF256::AddOrSubtract(
          product[i + j],
          m_field->Multiply(aCoeff, other->GetCoefficients()->operator[](j)));
    }
  }
  CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly();
  temp->Init(m_field, &product, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  return temp;
}
CFX_Int32Array* CBC_ReedSolomonDecoder::FindErrorLocations(
    CBC_ReedSolomonGF256Poly* errorLocator,
    int32_t& e) {
  int32_t numErrors = errorLocator->GetDegree();
  if (numErrors == 1) {
    CBC_AutoPtr<CFX_Int32Array> temp(new CFX_Int32Array);
    temp->Add(errorLocator->GetCoefficients(1));
    return temp.release();
  }
  CFX_Int32Array* tempT = new CFX_Int32Array;
  tempT->SetSize(numErrors);
  CBC_AutoPtr<CFX_Int32Array> result(tempT);
  int32_t ie = 0;
  for (int32_t i = 1; i < 256 && ie < numErrors; i++) {
    if (errorLocator->EvaluateAt(i) == 0) {
      (*result)[ie] = m_field->Inverse(i, ie);
      BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
      ie++;
    }
  }
  if (ie != numErrors) {
    e = BCExceptionDegreeNotMatchRoots;
    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  }
  return result.release();
}
CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::AddOrSubtract(
    CBC_ReedSolomonGF256Poly* other,
    int32_t& e) {
  if (IsZero())
    return other->Clone(e);
  if (other->IsZero())
    return Clone(e);

  CFX_Int32Array smallerCoefficients;
  smallerCoefficients.Copy(m_coefficients);
  CFX_Int32Array largerCoefficients;
  largerCoefficients.Copy(*(other->GetCoefficients()));
  if (smallerCoefficients.GetSize() > largerCoefficients.GetSize()) {
    CFX_Int32Array temp;
    temp.Copy(smallerCoefficients);
    smallerCoefficients.Copy(largerCoefficients);
    largerCoefficients.Copy(temp);
  }
  CFX_Int32Array sumDiff;
  sumDiff.SetSize(largerCoefficients.GetSize());
  int32_t lengthDiff =
      largerCoefficients.GetSize() - smallerCoefficients.GetSize();
  for (int32_t i = 0; i < lengthDiff; i++) {
    sumDiff[i] = largerCoefficients[i];
  }
  for (int32_t j = lengthDiff; j < largerCoefficients.GetSize(); j++) {
    sumDiff[j] = (CBC_ReedSolomonGF256::AddOrSubtract(
        smallerCoefficients[j - lengthDiff], largerCoefficients[j]));
  }
  CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly();
  temp->Init(m_field, &sumDiff, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
  return temp;
}
CFX_Int32Array* CBC_ReedSolomonDecoder::FindErrorMagnitudes(
    CBC_ReedSolomonGF256Poly* errorEvaluator,
    CFX_Int32Array* errorLocations,
    FX_BOOL dataMatrix,
    int32_t& e) {
  int32_t s = errorLocations->GetSize();
  CFX_Int32Array* temp = new CFX_Int32Array;
  temp->SetSize(s);
  CBC_AutoPtr<CFX_Int32Array> result(temp);
  for (int32_t i = 0; i < s; i++) {
    int32_t xiInverse = m_field->Inverse(errorLocations->operator[](i), e);
    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
    int32_t denominator = 1;
    for (int32_t j = 0; j < s; j++) {
      if (i != j) {
        denominator = m_field->Multiply(
            denominator, CBC_ReedSolomonGF256::AddOrSubtract(
                             1, m_field->Multiply(errorLocations->operator[](j),
                                                  xiInverse)));
      }
    }
    int32_t temp = m_field->Inverse(denominator, temp);
    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
    (*result)[i] =
        m_field->Multiply(errorEvaluator->EvaluateAt(xiInverse), temp);
  }
  return result.release();
}
CFX_WideString CBC_ErrorCorrection::encodeECC200(CFX_WideString codewords,
                                                 CBC_SymbolInfo* symbolInfo,
                                                 int32_t& e) {
  if (codewords.GetLength() != symbolInfo->m_dataCapacity) {
    e = BCExceptionIllegalArgument;
    return (FX_WCHAR*)"";
  }
  CFX_WideString sb;
  sb += codewords;
  int32_t blockCount = symbolInfo->getInterleavedBlockCount();
  if (blockCount == 1) {
    CFX_WideString ecc =
        createECCBlock(codewords, symbolInfo->m_errorCodewords, e);
    BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR*)"");
    sb += ecc;
  } else {
    CFX_Int32Array dataSizes;
    dataSizes.SetSize(blockCount);
    CFX_Int32Array errorSizes;
    errorSizes.SetSize(blockCount);
    CFX_Int32Array startPos;
    startPos.SetSize(blockCount);
    for (int32_t i = 0; i < blockCount; i++) {
      dataSizes[i] = symbolInfo->getDataLengthForInterleavedBlock(i + 1);
      errorSizes[i] = symbolInfo->getErrorLengthForInterleavedBlock(i + 1);
      startPos[i] = 0;
      if (i > 0) {
        startPos[i] = startPos[i - 1] + dataSizes[i];
      }
    }
    for (int32_t block = 0; block < blockCount; block++) {
      CFX_WideString temp;
      for (int32_t d = block; d < symbolInfo->m_dataCapacity; d += blockCount) {
        temp += (FX_WCHAR)codewords.GetAt(d);
      }
      CFX_WideString ecc = createECCBlock(temp, errorSizes[block], e);
      BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR*)"");
      int32_t pos = 0;
      for (int32_t l = block; l < errorSizes[block] * blockCount;
           l += blockCount) {
        sb.SetAt(symbolInfo->m_dataCapacity + l, ecc.GetAt(pos++));
      }
    }
  }
  return sb;
}
void CBC_ReedSolomonDecoder::Decode(CFX_Int32Array* received,
                                    int32_t twoS,
                                    int32_t& e) {
  CBC_ReedSolomonGF256Poly poly;
  poly.Init(m_field, received, e);
  BC_EXCEPTION_CHECK_ReturnVoid(e);
  CFX_Int32Array syndromeCoefficients;
  syndromeCoefficients.SetSize(twoS);
  FX_BOOL dataMatrix = FALSE;
  FX_BOOL noError = TRUE;
  for (int32_t i = 0; i < twoS; i++) {
    int32_t eval = poly.EvaluateAt(m_field->Exp(dataMatrix ? i + 1 : i));
    syndromeCoefficients[twoS - 1 - i] = eval;
    if (eval != 0) {
      noError = FALSE;
    }
  }
  if (noError) {
    return;
  }
  CBC_ReedSolomonGF256Poly syndrome;
  syndrome.Init(m_field, &syndromeCoefficients, e);
  BC_EXCEPTION_CHECK_ReturnVoid(e);
  CBC_ReedSolomonGF256Poly* rsg = m_field->BuildMonomial(twoS, 1, e);
  BC_EXCEPTION_CHECK_ReturnVoid(e);
  CBC_AutoPtr<CBC_ReedSolomonGF256Poly> temp(rsg);
  CFX_PtrArray* pa = RunEuclideanAlgorithm(temp.get(), &syndrome, twoS, e);
  BC_EXCEPTION_CHECK_ReturnVoid(e);
  CBC_AutoPtr<CFX_PtrArray> sigmaOmega(pa);
  CBC_AutoPtr<CBC_ReedSolomonGF256Poly> sigma(
      (CBC_ReedSolomonGF256Poly*)(*sigmaOmega)[0]);
  CBC_AutoPtr<CBC_ReedSolomonGF256Poly> omega(
      (CBC_ReedSolomonGF256Poly*)(*sigmaOmega)[1]);
  CFX_Int32Array* ia1 = FindErrorLocations(sigma.get(), e);
  BC_EXCEPTION_CHECK_ReturnVoid(e);
  CBC_AutoPtr<CFX_Int32Array> errorLocations(ia1);
  CFX_Int32Array* ia2 =
      FindErrorMagnitudes(omega.get(), errorLocations.get(), dataMatrix, e);
  BC_EXCEPTION_CHECK_ReturnVoid(e);
  CBC_AutoPtr<CFX_Int32Array> errorMagnitudes(ia2);
  for (int32_t k = 0; k < errorLocations->GetSize(); k++) {
    int32_t position =
        received->GetSize() - 1 - m_field->Log((*errorLocations)[k], e);
    BC_EXCEPTION_CHECK_ReturnVoid(e);
    if (position < 0) {
      e = BCExceptionBadErrorLocation;
      BC_EXCEPTION_CHECK_ReturnVoid(e);
    }
    (*received)[position] = CBC_ReedSolomonGF256::AddOrSubtract(
        (*received)[position], (*errorMagnitudes)[k]);
  }
}
void CBC_QRCoderDecoder::CorrectErrors(CFX_ByteArray* codewordBytes,
                                       int32_t numDataCodewords,
                                       int32_t& e) {
  int32_t numCodewords = codewordBytes->GetSize();
  CFX_Int32Array codewordsInts;
  codewordsInts.SetSize(numCodewords);
  for (int32_t i = 0; i < numCodewords; i++) {
    codewordsInts[i] = (int32_t)((*codewordBytes)[i] & 0xff);
  }
  int32_t numECCodewords = codewordBytes->GetSize() - numDataCodewords;
  m_rsDecoder->Decode(&codewordsInts, numECCodewords, e);
  BC_EXCEPTION_CHECK_ReturnVoid(e);
  for (int32_t k = 0; k < numDataCodewords; k++) {
    (*codewordBytes)[k] = (uint8_t)codewordsInts[k];
  }
}
CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Multiply(int32_t scalar,
                                                             int32_t& e) {
  if (scalar == 0)
    return m_field->GetZero()->Clone(e);
  if (scalar == 1)
    return Clone(e);

  int32_t size = m_coefficients.GetSize();
  CFX_Int32Array product;
  product.SetSize(size);
  for (int32_t i = 0; i < size; i++) {
    product[i] = m_field->Multiply(m_coefficients[i], scalar);
  }
  CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly();
  temp->Init(m_field, &product, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
  return temp;
}
CFX_Int32Array* CBC_DetectionResultRowIndicatorColumn::getRowHeights(
    int32_t& e) {
  CBC_BarcodeMetadata* barcodeMetadata = getBarcodeMetadata();
  if (barcodeMetadata == NULL) {
    e = BCExceptionCannotMetadata;
    return NULL;
  }
  adjustIncompleteIndicatorColumnRowNumbers(*barcodeMetadata);
  CFX_Int32Array* result = new CFX_Int32Array;
  result->SetSize(barcodeMetadata->getRowCount());
  for (int32_t i = 0; i < getCodewords()->GetSize(); i++) {
    CBC_Codeword* codeword = (CBC_Codeword*)getCodewords()->GetAt(i);
    if (codeword != NULL) {
      result->SetAt(codeword->getRowNumber(),
                    result->GetAt(codeword->getRowNumber()) + 1);
    }
  }
  return result;
}
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;
}
Beispiel #13
0
void CBC_DataMatrixDecoder::CorrectErrors(CFX_ByteArray& codewordBytes,
                                          int32_t numDataCodewords,
                                          int32_t& e) {
  int32_t numCodewords = codewordBytes.GetSize();
  CFX_Int32Array codewordsInts;
  codewordsInts.SetSize(numCodewords);
  int32_t i;
  for (i = 0; i < numCodewords; i++) {
    codewordsInts[i] = codewordBytes[i] & 0xFF;
  }
  int32_t numECCodewords = codewordBytes.GetSize() - numDataCodewords;
  m_rsDecoder->Decode(&codewordsInts, numECCodewords, e);
  if (e != BCExceptionNO) {
    e = BCExceptionChecksumException;
    return;
  }
  for (i = 0; i < numDataCodewords; i++) {
    codewordBytes[i] = (uint8_t)codewordsInts[i];
  }
}
void CBC_DataMatrixDecodedBitStreamParser::DecodeAnsiX12Segment(
    CBC_CommonBitSource* bits,
    CFX_ByteString& result,
    int32_t& e) {
  CFX_Int32Array cValues;
  cValues.SetSize(3);
  do {
    if (bits->Available() == 8) {
      return;
    }
    int32_t firstByte = bits->ReadBits(8, e);
    BC_EXCEPTION_CHECK_ReturnVoid(e);
    if (firstByte == 254) {
      return;
    }
    int32_t iTemp1 = bits->ReadBits(8, e);
    BC_EXCEPTION_CHECK_ReturnVoid(e);
    ParseTwoBytes(firstByte, iTemp1, cValues);
    int32_t i;
    for (i = 0; i < 3; i++) {
      int32_t cValue = cValues[i];
      if (cValue == 0) {
        BC_FX_ByteString_Append(result, 1, '\r');
      } else if (cValue == 1) {
        BC_FX_ByteString_Append(result, 1, '*');
      } else if (cValue == 2) {
        BC_FX_ByteString_Append(result, 1, '>');
      } else if (cValue == 3) {
        BC_FX_ByteString_Append(result, 1, ' ');
      } else if (cValue < 14) {
        BC_FX_ByteString_Append(result, 1, (FX_CHAR)(cValue + 44));
      } else if (cValue < 40) {
        BC_FX_ByteString_Append(result, 1, (FX_CHAR)(cValue + 51));
      } else {
        e = BCExceptionFormatException;
        return;
      }
    }
  } while (bits->Available() > 0);
}
int32_t CBC_DecodedBitStreamPaser::byteCompaction(int32_t mode,
                                                  CFX_Int32Array& codewords,
                                                  int32_t codeIndex,
                                                  CFX_ByteString& result) {
  if (mode == BYTE_COMPACTION_MODE_LATCH) {
    int32_t count = 0;
    int64_t value = 0;
    FX_WORD* decodedData = FX_Alloc(FX_WORD, 6);
    CFX_Int32Array byteCompactedCodewords;
    byteCompactedCodewords.SetSize(6);
    FX_BOOL end = FALSE;
    int32_t nextCode = codewords[codeIndex++];
    while ((codeIndex < codewords[0]) && !end) {
      byteCompactedCodewords[count++] = nextCode;
      value = 900 * value + nextCode;
      nextCode = codewords[codeIndex++];
      if (nextCode == TEXT_COMPACTION_MODE_LATCH ||
          nextCode == BYTE_COMPACTION_MODE_LATCH ||
          nextCode == NUMERIC_COMPACTION_MODE_LATCH ||
          nextCode == BYTE_COMPACTION_MODE_LATCH_6 ||
          nextCode == BEGIN_MACRO_PDF417_CONTROL_BLOCK ||
          nextCode == BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||
          nextCode == MACRO_PDF417_TERMINATOR) {
        codeIndex--;
        end = TRUE;
      } else {
        if ((count % 5 == 0) && (count > 0)) {
          int32_t j = 0;
          for (; j < 6; ++j) {
            decodedData[5 - j] = (FX_WORD)(value % 256);
            value >>= 8;
          }
          for (j = 0; j < 6; ++j) {
            result += (FX_CHAR)decodedData[j];
          }
          count = 0;
        }
      }
    }
CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::MultiplyByMonomial(
    int32_t degree,
    int32_t coefficient,
    int32_t& e) {
  if (degree < 0) {
    e = BCExceptionDegreeIsNegative;
    return nullptr;
  }
  if (coefficient == 0)
    return m_field->GetZero()->Clone(e);

  int32_t size = m_coefficients.GetSize();
  CFX_Int32Array product;
  product.SetSize(size + degree);
  for (int32_t i = 0; i < size; i++) {
    product[i] = (m_field->Multiply(m_coefficients[i], coefficient));
  }
  CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly();
  temp->Init(m_field, &product, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
  return temp;
}
Beispiel #17
0
CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusGF::buildMonomial(
    int32_t degree,
    int32_t coefficient,
    int32_t& e) {
  if (degree < 0) {
    e = BCExceptionIllegalArgument;
    return NULL;
  }
  CBC_PDF417ECModulusPoly* modulusPoly = NULL;
  if (coefficient == 0) {
    modulusPoly = new CBC_PDF417ECModulusPoly(m_zero->getField(),
                                              m_zero->getCoefficients(), e);
    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
    return modulusPoly;
  }
  CFX_Int32Array coefficients;
  coefficients.SetSize(degree + 1);
  coefficients[0] = coefficient;
  modulusPoly = new CBC_PDF417ECModulusPoly(this, coefficients, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  return modulusPoly;
}
int32_t CBC_HighLevelEncoder::lookAheadTest(CFX_WideString msg,
                                            int32_t startpos,
                                            int32_t currentMode) {
  if (startpos >= msg.GetLength()) {
    return currentMode;
  }
  CFX_FloatArray charCounts;
  if (currentMode == ASCII_ENCODATION) {
    charCounts.Add(0);
    charCounts.Add(1);
    charCounts.Add(1);
    charCounts.Add(1);
    charCounts.Add(1);
    charCounts.Add(1.25f);
  } else {
    charCounts.Add(1);
    charCounts.Add(2);
    charCounts.Add(2);
    charCounts.Add(2);
    charCounts.Add(2);
    charCounts.Add(2.25f);
    charCounts[currentMode] = 0;
  }
  int32_t charsProcessed = 0;
  while (TRUE) {
    if ((startpos + charsProcessed) == msg.GetLength()) {
      FX_DWORD min = std::numeric_limits<int32_t>::max();
      CFX_ByteArray mins;
      mins.SetSize(6);
      CFX_Int32Array intCharCounts;
      intCharCounts.SetSize(6);
      min = findMinimums(charCounts, intCharCounts, min, mins);
      int32_t minCount = getMinimumCount(mins);
      if (intCharCounts[ASCII_ENCODATION] == min) {
        return ASCII_ENCODATION;
      }
      if (minCount == 1 && mins[BASE256_ENCODATION] > 0) {
        return BASE256_ENCODATION;
      }
      if (minCount == 1 && mins[EDIFACT_ENCODATION] > 0) {
        return EDIFACT_ENCODATION;
      }
      if (minCount == 1 && mins[TEXT_ENCODATION] > 0) {
        return TEXT_ENCODATION;
      }
      if (minCount == 1 && mins[X12_ENCODATION] > 0) {
        return X12_ENCODATION;
      }
      return C40_ENCODATION;
    }
    FX_WCHAR c = msg.GetAt(startpos + charsProcessed);
    charsProcessed++;
    if (isDigit(c)) {
      charCounts[ASCII_ENCODATION] += 0.5;
    } else if (isExtendedASCII(c)) {
      charCounts[ASCII_ENCODATION] =
          (FX_FLOAT)ceil(charCounts[ASCII_ENCODATION]);
      charCounts[ASCII_ENCODATION] += 2;
    } else {
      charCounts[ASCII_ENCODATION] =
          (FX_FLOAT)ceil(charCounts[ASCII_ENCODATION]);
      charCounts[ASCII_ENCODATION]++;
    }
    if (isNativeC40(c)) {
      charCounts[C40_ENCODATION] += 2.0f / 3.0f;
    } else if (isExtendedASCII(c)) {
      charCounts[C40_ENCODATION] += 8.0f / 3.0f;
    } else {
      charCounts[C40_ENCODATION] += 4.0f / 3.0f;
    }
    if (isNativeText(c)) {
      charCounts[TEXT_ENCODATION] += 2.0f / 3.0f;
    } else if (isExtendedASCII(c)) {
      charCounts[TEXT_ENCODATION] += 8.0f / 3.0f;
    } else {
      charCounts[TEXT_ENCODATION] += 4.0f / 3.0f;
    }
    if (isNativeX12(c)) {
      charCounts[X12_ENCODATION] += 2.0f / 3.0f;
    } else if (isExtendedASCII(c)) {
      charCounts[X12_ENCODATION] += 13.0f / 3.0f;
    } else {
      charCounts[X12_ENCODATION] += 10.0f / 3.0f;
    }
    if (isNativeEDIFACT(c)) {
      charCounts[EDIFACT_ENCODATION] += 3.0f / 4.0f;
    } else if (isExtendedASCII(c)) {
      charCounts[EDIFACT_ENCODATION] += 17.0f / 4.0f;
    } else {
      charCounts[EDIFACT_ENCODATION] += 13.0f / 4.0f;
    }
    if (isSpecialB256(c)) {
      charCounts[BASE256_ENCODATION] += 4;
    } else {
      charCounts[BASE256_ENCODATION]++;
    }
    if (charsProcessed >= 4) {
      CFX_Int32Array intCharCounts;
      intCharCounts.SetSize(6);
      CFX_ByteArray mins;
      mins.SetSize(6);
      findMinimums(charCounts, intCharCounts,
                   std::numeric_limits<int32_t>::max(), mins);
      int32_t minCount = getMinimumCount(mins);
      if (intCharCounts[ASCII_ENCODATION] < intCharCounts[BASE256_ENCODATION] &&
          intCharCounts[ASCII_ENCODATION] < intCharCounts[C40_ENCODATION] &&
          intCharCounts[ASCII_ENCODATION] < intCharCounts[TEXT_ENCODATION] &&
          intCharCounts[ASCII_ENCODATION] < intCharCounts[X12_ENCODATION] &&
          intCharCounts[ASCII_ENCODATION] < intCharCounts[EDIFACT_ENCODATION]) {
        return ASCII_ENCODATION;
      }
      if (intCharCounts[BASE256_ENCODATION] < intCharCounts[ASCII_ENCODATION] ||
          (mins[C40_ENCODATION] + mins[TEXT_ENCODATION] + mins[X12_ENCODATION] +
           mins[EDIFACT_ENCODATION]) == 0) {
        return BASE256_ENCODATION;
      }
      if (minCount == 1 && mins[EDIFACT_ENCODATION] > 0) {
        return EDIFACT_ENCODATION;
      }
      if (minCount == 1 && mins[TEXT_ENCODATION] > 0) {
        return TEXT_ENCODATION;
      }
      if (minCount == 1 && mins[X12_ENCODATION] > 0) {
        return X12_ENCODATION;
      }
      if (intCharCounts[C40_ENCODATION] + 1 < intCharCounts[ASCII_ENCODATION] &&
          intCharCounts[C40_ENCODATION] + 1 <
              intCharCounts[BASE256_ENCODATION] &&
          intCharCounts[C40_ENCODATION] + 1 <
              intCharCounts[EDIFACT_ENCODATION] &&
          intCharCounts[C40_ENCODATION] + 1 < intCharCounts[TEXT_ENCODATION]) {
        if (intCharCounts[C40_ENCODATION] < intCharCounts[X12_ENCODATION]) {
          return C40_ENCODATION;
        }
        if (intCharCounts[C40_ENCODATION] == intCharCounts[X12_ENCODATION]) {
          int32_t p = startpos + charsProcessed + 1;
          while (p < msg.GetLength()) {
            FX_WCHAR tc = msg.GetAt(p);
            if (isX12TermSep(tc)) {
              return X12_ENCODATION;
            }
            if (!isNativeX12(tc)) {
              break;
            }
            p++;
          }
          return C40_ENCODATION;
        }
      }
    }
  }
}
Beispiel #19
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;
}
void CBC_DataMatrixDecodedBitStreamParser::DecodeTextSegment(
    CBC_CommonBitSource* bits,
    CFX_ByteString& result,
    int32_t& e) {
  FX_BOOL upperShift = FALSE;
  CFX_Int32Array cValues;
  cValues.SetSize(3);
  int32_t shift = 0;
  do {
    if (bits->Available() == 8) {
      return;
    }
    int32_t firstByte = bits->ReadBits(8, e);
    BC_EXCEPTION_CHECK_ReturnVoid(e);
    if (firstByte == 254) {
      return;
    }
    int32_t inTp = bits->ReadBits(8, e);
    BC_EXCEPTION_CHECK_ReturnVoid(e);
    ParseTwoBytes(firstByte, inTp, cValues);
    for (int32_t i = 0; i < 3; i++) {
      int32_t cValue = cValues[i];
      switch (shift) {
        case 0:
          if (cValue < 3) {
            shift = cValue + 1;
          } else if (cValue < 40) {
            FX_CHAR textChar = TEXT_BASIC_SET_CHARS[cValue];
            if (upperShift) {
              result += (FX_CHAR)(textChar + 128);
              upperShift = FALSE;
            } else {
              result += textChar;
            }
          } else {
            e = BCExceptionFormatException;
            return;
          }
          break;
        case 1:
          if (upperShift) {
            result += (FX_CHAR)(cValue + 128);
            upperShift = FALSE;
          } else {
            result += cValue;
          }
          shift = 0;
          break;
        case 2:
          if (cValue < 27) {
            FX_CHAR c40char = C40_SHIFT2_SET_CHARS[cValue];
            if (upperShift) {
              result += (FX_CHAR)(c40char + 128);
              upperShift = FALSE;
            } else {
              result += c40char;
            }
          } else if (cValue == 27) {
            e = BCExceptionFormatException;
            return;
          } else if (cValue == 30) {
            upperShift = TRUE;
          } else {
            e = BCExceptionFormatException;
            return;
          }
          shift = 0;
          break;
        case 3:
          if (cValue < 19) {
            FX_CHAR textChar = TEXT_SHIFT3_SET_CHARS[cValue];
            if (upperShift) {
              result += (FX_CHAR)(textChar + 128);
              upperShift = FALSE;
            } else {
              result += textChar;
            }
            shift = 0;
          } else {
            e = BCExceptionFormatException;
            return;
          }
          break;
        default:
          break;
          e = BCExceptionFormatException;
          return;
      }
    }
  } while (bits->Available() > 0);
}