CBC_CommonDecoderResult* CBC_DataMatrixDecodedBitStreamParser::Decode(
    CFX_ByteArray& bytes,
    int32_t& e) {
  CBC_CommonBitSource bits(&bytes);
  CFX_ByteString result;
  CFX_ByteString resultTrailer;
  CFX_Int32Array byteSegments;
  int32_t mode = ASCII_ENCODE;
  do {
    if (mode == 1) {
      mode = DecodeAsciiSegment(&bits, result, resultTrailer, e);
      BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
    } else {
      switch (mode) {
        case 2:
          DecodeC40Segment(&bits, result, e);
          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
          break;
        case 3:
          DecodeTextSegment(&bits, result, e);
          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
          break;
        case 4:
          DecodeAnsiX12Segment(&bits, result, e);
          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
          break;
        case 5:
          DecodeEdifactSegment(&bits, result, e);
          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
          break;
        case 6:
          DecodeBase256Segment(&bits, result, byteSegments, e);
          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
          break;
        default:
          NULL;
          e = BCExceptionFormatException;
          return NULL;
      }
      mode = ASCII_ENCODE;
    }
  } while (mode != PAD_ENCODE && bits.Available() > 0);
  if (resultTrailer.GetLength() > 0) {
    result += resultTrailer;
  }
  CBC_CommonDecoderResult* tempCp = new CBC_CommonDecoderResult();
  tempCp->Init(bytes, result,
               (byteSegments.GetSize() <= 0) ? CFX_Int32Array() : byteSegments,
               NULL, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  return tempCp;
}
CBC_CommonDecoderResult* CBC_DecodedBitStreamPaser::decode(
    CFX_Int32Array& codewords,
    CFX_ByteString ecLevel,
    int32_t& e) {
  CFX_ByteString result;
  int32_t codeIndex = 1;
  int32_t code = codewords.GetAt(codeIndex);
  codeIndex++;
  CBC_PDF417ResultMetadata* resultMetadata = new CBC_PDF417ResultMetadata;
  while (codeIndex < codewords[0]) {
    switch (code) {
      case TEXT_COMPACTION_MODE_LATCH:
        codeIndex = textCompaction(codewords, codeIndex, result);
        break;
      case BYTE_COMPACTION_MODE_LATCH:
        codeIndex = byteCompaction(code, codewords, codeIndex, result);
        break;
      case NUMERIC_COMPACTION_MODE_LATCH:
        codeIndex = numericCompaction(codewords, codeIndex, result, e);
        BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
        break;
      case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
        codeIndex = byteCompaction(code, codewords, codeIndex, result);
        break;
      case BYTE_COMPACTION_MODE_LATCH_6:
        codeIndex = byteCompaction(code, codewords, codeIndex, result);
        break;
      case BEGIN_MACRO_PDF417_CONTROL_BLOCK:
        codeIndex = decodeMacroBlock(codewords, codeIndex, resultMetadata, e);
        if (e != BCExceptionNO) {
          delete resultMetadata;
          return NULL;
        }
        break;
      default:
        codeIndex--;
        codeIndex = textCompaction(codewords, codeIndex, result);
        break;
    }
    if (codeIndex < codewords.GetSize()) {
      code = codewords[codeIndex++];
    } else {
      e = BCExceptionFormatInstance;
      delete resultMetadata;
      return NULL;
    }
  }
  if (result.GetLength() == 0) {
    e = BCExceptionFormatInstance;
    delete resultMetadata;
    return NULL;
  }
  CFX_ByteArray rawBytes;
  CFX_PtrArray byteSegments;
  CBC_CommonDecoderResult* tempCd = new CBC_CommonDecoderResult();
  tempCd->Init(rawBytes, result, byteSegments, ecLevel, e);
  if (e != BCExceptionNO) {
    delete resultMetadata;
    return NULL;
  }
  tempCd->setOther(resultMetadata);
  return tempCd;
}
CBC_CommonDecoderResult* CBC_QRDecodedBitStreamParser::Decode(
    CFX_ByteArray* bytes,
    CBC_QRCoderVersion* version,
    CBC_QRCoderErrorCorrectionLevel* ecLevel,
    int32_t byteModeDecode,
    int32_t& e) {
  CBC_CommonBitSource bits(bytes);
  CFX_ByteString result;
  CBC_CommonCharacterSetECI* currentCharacterSetECI = NULL;
  FX_BOOL fc1Infact = FALSE;
  CFX_Int32Array byteSegments;
  CBC_QRCoderMode* mode = NULL;
  do {
    if (bits.Available() < 4) {
      mode = CBC_QRCoderMode::sTERMINATOR;
    } else {
      int32_t iTemp1 = bits.ReadBits(4, e);
      BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
      mode = CBC_QRCoderMode::ForBits(iTemp1, e);
      BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
      if (mode == NULL) {
        e = BCExceptionUnSupportMode;
        BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
      }
    }
    if (!(mode == CBC_QRCoderMode::sTERMINATOR)) {
      if (mode == CBC_QRCoderMode::sFNC1_FIRST_POSITION ||
          mode == CBC_QRCoderMode::sFNC1_SECOND_POSITION) {
        fc1Infact = TRUE;
      } else if (mode == CBC_QRCoderMode::sSTRUCTURED_APPEND) {
        bits.ReadBits(16, e);
        BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
      } else if (mode == CBC_QRCoderMode::sECI) {
        int32_t value = ParseECIValue(&bits, e);
        BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
        currentCharacterSetECI =
            CBC_CommonCharacterSetECI::GetCharacterSetECIByValue(value);
      } else {
        if (mode == CBC_QRCoderMode::sGBK) {
          bits.ReadBits(4, e);
          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
        }
        int32_t numBits = mode->GetCharacterCountBits(version, e);
        BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
        int32_t count = bits.ReadBits(numBits, e);
        BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
        if (mode == CBC_QRCoderMode::sNUMERIC) {
          DecodeNumericSegment(&bits, result, count, e);
          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
        } else if (mode == CBC_QRCoderMode::sALPHANUMERIC) {
          DecodeAlphanumericSegment(&bits, result, count, fc1Infact, e);
          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
        } else if (mode == CBC_QRCoderMode::sBYTE) {
          DecodeByteSegment(&bits, result, count, currentCharacterSetECI,
                            &byteSegments, byteModeDecode, e);
          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
        } else if (mode == CBC_QRCoderMode::sGBK) {
          DecodeGBKSegment(&bits, result, count, e);
          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
        } else if (mode == CBC_QRCoderMode::sKANJI) {
          DecodeKanjiSegment(&bits, result, count, e);
          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
        } else {
          e = BCExceptionUnSupportMode;
          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
        }
      }
    }
  } while (!(mode == CBC_QRCoderMode::sTERMINATOR));
  CBC_CommonDecoderResult* tempCd = new CBC_CommonDecoderResult();
  tempCd->Init(*bytes, result, byteSegments, ecLevel, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
  return tempCd;
}