Esempio n. 1
0
bool EncodeSourceData(char *lpsSource, int ncLength, int nVerGroup)
{
	int i, j;
	int ncSrcBits, ncDstBits;
	int nBlock = 0;
	int ncComplete = 0; 
	WORD wBinCode;

	memset(m_nBlockLength, 0, sizeof(m_nBlockLength));

	for (m_ncDataBlock = i = 0; i < ncLength; ++i)
	{
		BYTE byMode;

		if (i < ncLength - 1 && IsKanjiData(lpsSource[i], lpsSource[i + 1]))
			byMode = QR_MODE_KANJI;
		else if (IsNumeralData(lpsSource[i]))
			byMode = QR_MODE_NUMERAL;
		else if (IsAlphabetData(lpsSource[i]))
			byMode = QR_MODE_ALPHABET;
		else
			byMode = QR_MODE_8BIT;

		if (i == 0)
			m_byBlockMode[0] = byMode;

		if (m_byBlockMode[m_ncDataBlock] != byMode)
			m_byBlockMode[++m_ncDataBlock] = byMode;

		++m_nBlockLength[m_ncDataBlock];

		if (byMode == QR_MODE_KANJI)
		{
			++m_nBlockLength[m_ncDataBlock];
			++i;
		}
	}

	++m_ncDataBlock;

	while (nBlock < m_ncDataBlock - 1)
	{
		int ncJoinFront, ncJoinBehind; 
		int nJoinPosition = 0; 

		if ((m_byBlockMode[nBlock] == QR_MODE_NUMERAL  && m_byBlockMode[nBlock + 1] == QR_MODE_ALPHABET) ||
			(m_byBlockMode[nBlock] == QR_MODE_ALPHABET && m_byBlockMode[nBlock + 1] == QR_MODE_NUMERAL))
		{
			ncSrcBits = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) +
						GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup);

			ncDstBits = GetBitLength(QR_MODE_ALPHABET, m_nBlockLength[nBlock] + m_nBlockLength[nBlock + 1], nVerGroup);

			if (ncSrcBits > ncDstBits)
			{
				if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT)
				{
					ncJoinFront = GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock - 1] + m_nBlockLength[nBlock], nVerGroup) +
								  GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup);

					if (ncJoinFront > ncDstBits + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock - 1], nVerGroup))
						ncJoinFront = 0; 
				}
				else
					ncJoinFront = 0;

				if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT)
				{
					ncJoinBehind = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) +
								   GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock + 1] + m_nBlockLength[nBlock + 2], nVerGroup);

					if (ncJoinBehind > ncDstBits + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock + 2], nVerGroup))
						ncJoinBehind = 0; 
				}
				else
					ncJoinBehind = 0;

				if (ncJoinFront != 0 && ncJoinBehind != 0)
				{
					nJoinPosition = (ncJoinFront < ncJoinBehind) ? -1 : 1;
				}
				else
				{
					nJoinPosition = (ncJoinFront != 0) ? -1 : ((ncJoinBehind != 0) ? 1 : 0);
				}

				if (nJoinPosition != 0)
				{
					if (nJoinPosition == -1)
					{
						m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock];

						for (i = nBlock; i < m_ncDataBlock - 1; ++i)
						{
							m_byBlockMode[i]  = m_byBlockMode[i + 1];
							m_nBlockLength[i] = m_nBlockLength[i + 1];
						}
					}
					else
					{
						m_byBlockMode[nBlock + 1] = QR_MODE_8BIT;
						m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2];

						for (i = nBlock + 2; i < m_ncDataBlock - 1; ++i)
						{
							m_byBlockMode[i]  = m_byBlockMode[i + 1];
							m_nBlockLength[i] = m_nBlockLength[i + 1];
						}
					}

					--m_ncDataBlock;
				}
				else
				{
					if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_ALPHABET)
					{
						m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2];

						for (i = nBlock + 2; i < m_ncDataBlock - 1; ++i)
						{
							m_byBlockMode[i]  = m_byBlockMode[i + 1];
							m_nBlockLength[i] = m_nBlockLength[i + 1];
						}

						--m_ncDataBlock;
					}

					m_byBlockMode[nBlock] = QR_MODE_ALPHABET;
					m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1];

					for (i = nBlock + 1; i < m_ncDataBlock - 1; ++i)
					{
						m_byBlockMode[i]  = m_byBlockMode[i + 1];
						m_nBlockLength[i] = m_nBlockLength[i + 1];
					}

					--m_ncDataBlock;

					if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_ALPHABET)
					{
						m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock];

						for (i = nBlock; i < m_ncDataBlock - 1; ++i)
						{
							m_byBlockMode[i]  = m_byBlockMode[i + 1];
							m_nBlockLength[i] = m_nBlockLength[i + 1];
						}

						--m_ncDataBlock;
					}
				}

				continue;
			}
		}

		++nBlock; 
	}

	nBlock = 0;

	while (nBlock < m_ncDataBlock - 1)
	{
		ncSrcBits = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup)
					+ GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup);

		ncDstBits = GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock] + m_nBlockLength[nBlock + 1], nVerGroup);

		if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT)
			ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]);

		if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT)
			ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]);

		if (ncSrcBits > ncDstBits)
		{
			if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT)
			{
				m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock];

				for (i = nBlock; i < m_ncDataBlock - 1; ++i)
				{
					m_byBlockMode[i]  = m_byBlockMode[i + 1];
					m_nBlockLength[i] = m_nBlockLength[i + 1];
				}

				--m_ncDataBlock;
				--nBlock;
			}

			if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT)
			{
				m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2];

				for (i = nBlock + 2; i < m_ncDataBlock - 1; ++i)
				{
					m_byBlockMode[i]  = m_byBlockMode[i + 1];
					m_nBlockLength[i] = m_nBlockLength[i + 1];
				}

				--m_ncDataBlock;
			}

			m_byBlockMode[nBlock] = QR_MODE_8BIT;
			m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1];

			for (i = nBlock + 1; i < m_ncDataBlock - 1; ++i)
			{
				m_byBlockMode[i]  = m_byBlockMode[i + 1];
				m_nBlockLength[i] = m_nBlockLength[i + 1];
			}

			--m_ncDataBlock;

			if (nBlock >= 1)
				--nBlock;

			continue;
		}

		++nBlock; 
	}

	m_ncDataCodeWordBit = 0; 

	memset(m_byDataCodeWord, 0, MAX_DATACODEWORD);

	for (i = 0; i < m_ncDataBlock && m_ncDataCodeWordBit != -1; ++i)
	{
		if (m_byBlockMode[i] == QR_MODE_NUMERAL)
		{
			m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 1, 4); 

			m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (WORD)m_nBlockLength[i], nIndicatorLenNumeral[nVerGroup]);

			for (j = 0; j < m_nBlockLength[i]; j += 3)
			{
				if (j < m_nBlockLength[i] - 2)
				{
					wBinCode = (WORD)(((lpsSource[ncComplete + j]	  - '0') * 100) +
									  ((lpsSource[ncComplete + j + 1] - '0') * 10) +
									   (lpsSource[ncComplete + j + 2] - '0'));

					m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 10);
				}
				else if (j == m_nBlockLength[i] - 2)
				{
					wBinCode = (WORD)(((lpsSource[ncComplete + j] - '0') * 10) +
									   (lpsSource[ncComplete + j + 1] - '0'));

					m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 7);
				}
				else if (j == m_nBlockLength[i] - 1)
				{
					wBinCode = (WORD)(lpsSource[ncComplete + j] - '0');

					m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 4);
				}
			}

			ncComplete += m_nBlockLength[i];
		}

		else if (m_byBlockMode[i] == QR_MODE_ALPHABET)
		{
			m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 2, 4);

			m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (WORD)m_nBlockLength[i], nIndicatorLenAlphabet[nVerGroup]);

			for (j = 0; j < m_nBlockLength[i]; j += 2)
			{
				if (j < m_nBlockLength[i] - 1)
				{
					wBinCode = (WORD)((AlphabetToBinaly(lpsSource[ncComplete + j]) * 45) +
									   AlphabetToBinaly(lpsSource[ncComplete + j + 1]));

					m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 11);
				}
				else
				{
					wBinCode = (WORD)AlphabetToBinaly(lpsSource[ncComplete + j]);

					m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 6);
				}
			}

			ncComplete += m_nBlockLength[i];
		}

		else if (m_byBlockMode[i] == QR_MODE_8BIT)
		{
			m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 4, 4);

			m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (WORD)m_nBlockLength[i], nIndicatorLen8Bit[nVerGroup]);

			for (j = 0; j < m_nBlockLength[i]; ++j)
			{
				m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (WORD)lpsSource[ncComplete + j], 8);
			}

			ncComplete += m_nBlockLength[i];
		}
		else
		{
			m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 8, 4);

			m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (WORD)(m_nBlockLength[i] / 2), nIndicatorLenKanji[nVerGroup]);

			for (j = 0; j < m_nBlockLength[i] / 2; ++j)
			{
				WORD wBinCode = KanjiToBinaly((WORD)(((BYTE)lpsSource[ncComplete + (j * 2)] << 8) + (BYTE)lpsSource[ncComplete + (j * 2) + 1]));

				m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 13);
			}

			ncComplete += m_nBlockLength[i];
		}
	}

	return (m_ncDataCodeWordBit != -1);
}
Esempio n. 2
0
int qr_encode(int level, int version, const char *source, size_t source_len, uint8_t *result)
{
	int i, j;
	const bool auto_extent = 0;
	m_nLevel = level;
	m_nMaskingNo = -1;

	memset(result, 0, QR_MAX_BITDATA);
	// If the data length is not specified, acquired by lstrlen
	size_t ncLength = source_len > 0 ? source_len : strlen(source);

	if (ncLength == 0) {
		return -1; // No data
	}

	// Check version (model number)

	nEncodeVersion = GetEncodeVersion(version, source, ncLength);

	if (nEncodeVersion == 0) {
		return -1; // Over-capacity
	}
	if (version == 0) {
		// Auto Part
		m_nVersion = nEncodeVersion;
	} else {
		if (nEncodeVersion <= version) {
			m_nVersion = version;
		} else {
			if (auto_extent) {
				m_nVersion = nEncodeVersion; // Automatic extended version (model number)
			} else {
				return -1; // Over-capacity
			}
		}
	}

	// Terminator addition code "0000"
	int ncDataCodeWord = QR_VersonInfo[m_nVersion].ncDataCodeWord[level];

	int ncTerminater = (ncDataCodeWord * 8) - m_ncDataCodeWordBit;
	if (ncTerminater < 4) {
		ncTerminater = 4;
	}

	if (ncTerminater > 0) {
		m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 0, ncTerminater);
	}

	// Additional padding code "11101100, 00010001"
	uint8_t byPaddingCode = 0xec;

	for (i = (m_ncDataCodeWordBit + 7) / 8; i < ncDataCodeWord; i++) {
		m_byDataCodeWord[i] = byPaddingCode;

		byPaddingCode = (uint8_t)(byPaddingCode == 0xec ? 0x11 : 0xec);
	}

	// Calculated the total clear area code word
	m_ncAllCodeWord = QR_VersonInfo[m_nVersion].ncAllCodeWord;

	memset(m_byAllCodeWord, 0, sizeof(m_byAllCodeWord));

	int nDataCwIndex = 0;	// Position data processing code word

	// Division number data block
	int ncBlock1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[level].ncRSBlock;

	int ncBlock2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[level].ncRSBlock;

	int ncBlockSum = ncBlock1 + ncBlock2;

	int nBlockNo = 0; // Block number in the process

	// The number of data code words by block
	int ncDataCw1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[level].ncDataCodeWord;

	int ncDataCw2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[level].ncDataCodeWord;

	// Code word interleaving data placement
	for (i = 0; i < ncBlock1; i++) {
		for (j = 0; j < ncDataCw1; j++) {
			m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++];
		}

		nBlockNo++;
	}

	for (i = 0; i < ncBlock2; i++) {
		for (j = 0; j < ncDataCw2; j++) {
			if (j < ncDataCw1) {
				m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++];
			} else {
				// 2 minute fraction block placement event
				m_byAllCodeWord[(ncBlockSum * ncDataCw1) + i] = m_byDataCodeWord[nDataCwIndex++];
			}
		}
		nBlockNo++;
	}

	// RS code words by block number (currently the same number)
	int ncRSCw1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[level].ncAllCodeWord - ncDataCw1;
	int ncRSCw2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[level].ncAllCodeWord - ncDataCw2;

	// RS code word is calculated

	nDataCwIndex = 0;
	nBlockNo = 0;

	for (i = 0; i < ncBlock1; i++) {
		memset(m_byRSWork, 0, sizeof(m_byRSWork));
		memmove(m_byRSWork, m_byDataCodeWord + nDataCwIndex, ncDataCw1);
		GetRSCodeWord(m_byRSWork, ncDataCw1, ncRSCw1);
		// RS code word placement
		for (j = 0; j < ncRSCw1; j++) {
			m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j];
		}
		nDataCwIndex += ncDataCw1;
		nBlockNo++;
	}

	for (i = 0; i < ncBlock2; i++) {
		memset(m_byRSWork, 0, sizeof(m_byRSWork));
		memmove(m_byRSWork, m_byDataCodeWord + nDataCwIndex, ncDataCw2);
		GetRSCodeWord(m_byRSWork, ncDataCw2, ncRSCw2);
		// RS code word placement
		for (j = 0; j < ncRSCw2; j++) {
			m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j];
		}
		nDataCwIndex += ncDataCw2;
		nBlockNo++;
	}

	m_nSymbleSize = m_nVersion * 4 + 17;

	// Module placement
	FormatModule();

	for (i = 0; i < m_nSymbleSize; i++) {
		for (j = 0; j < m_nSymbleSize; j++) {
			if (!m_byModuleData[i][j]) {
				putBitToPos((j * m_nSymbleSize) + i + 1, 0, result);
			} else {
				putBitToPos((j * m_nSymbleSize) + i + 1, 1, result);
			}
		}
	}
	return m_nSymbleSize;
}
Esempio n. 3
0
bool EncodeData(char *lpsSource)
{
	int i, j;
	int nEncodeVersion, ncDataCodeWord, ncTerminater;
	BYTE byPaddingCode = 0xec;
	int nDataCwIndex = 0, ncBlock1, ncBlock2, ncBlockSum; 
	int nBlockNo = 0, ncDataCw1, ncDataCw2;
	int ncRSCw1, ncRSCw2;
  
	int nVersion = 1;
	int bAutoExtent = 1;
	int ncLength =  strlen(lpsSource);;
	
	m_nLevel = 2;
	m_nMaskingNo = 0;

 //»ñÈ¡°æ±¾ºÅ
	nEncodeVersion = GetEncodeVersion(nVersion, lpsSource, ncLength);
	if(nEncodeVersion == 0) return FALSE; 

	
	if (nEncodeVersion <= nVersion) m_nVersion = nVersion;
  else if (bAutoExtent)           m_nVersion = nEncodeVersion; 
	
	
	ncDataCodeWord = QR_VersonInfo[m_nVersion].ncDataCodeWord[m_nLevel];

	ncTerminater = min(4, (ncDataCodeWord * 8) - m_ncDataCodeWordBit);

	if (ncTerminater > 0) m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 0, ncTerminater);

	for (i = (m_ncDataCodeWordBit + 7) / 8; i < ncDataCodeWord; ++i)
	{
		m_byDataCodeWord[i] = byPaddingCode;

		byPaddingCode = (BYTE)(byPaddingCode == 0xec ? 0x11 : 0xec);
	}

	m_ncAllCodeWord = QR_VersonInfo[m_nVersion].ncAllCodeWord;
	memset(m_byAllCodeWord, 0, m_ncAllCodeWord);

	ncBlock1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[m_nLevel].ncRSBlock;
	ncBlock2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[m_nLevel].ncRSBlock;
	ncBlockSum = ncBlock1 + ncBlock2;

	ncDataCw1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[m_nLevel].ncDataCodeWord;
	ncDataCw2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[m_nLevel].ncDataCodeWord;

	for (i = 0; i < ncBlock1; ++i)
	{
		for (j = 0; j < ncDataCw1; ++j)
		{
			m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++];
		}

		++nBlockNo;
	}

	for (i = 0; i < ncBlock2; ++i)
	{
		for (j = 0; j < ncDataCw2; ++j)
		{
			if (j < ncDataCw1)
			{
				m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++];
			}
			else
			{
				m_byAllCodeWord[(ncBlockSum * ncDataCw1) + i]  = m_byDataCodeWord[nDataCwIndex++];
			}	
		}

		++nBlockNo;
	}

	ncRSCw1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[m_nLevel].ncAllCodeWord - ncDataCw1;
	ncRSCw2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[m_nLevel].ncAllCodeWord - ncDataCw2;

	nDataCwIndex = 0;
	nBlockNo = 0;

	for (i = 0; i < ncBlock1; ++i)
	{
		memset(m_byRSWork, 0, sizeof(m_byRSWork));

		memmove(m_byRSWork, m_byDataCodeWord + nDataCwIndex, ncDataCw1);

		GetRSCodeWord(m_byRSWork, ncDataCw1, ncRSCw1);

		for (j = 0; j < ncRSCw1; ++j)
		{
			m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j];
		}

		nDataCwIndex += ncDataCw1;
		++nBlockNo;
	}

	for (i = 0; i < ncBlock2; ++i)
	{
		memset(m_byRSWork, 0, sizeof(m_byRSWork));

		memmove(m_byRSWork, m_byDataCodeWord + nDataCwIndex, ncDataCw2);

		GetRSCodeWord(m_byRSWork, ncDataCw2, ncRSCw2);

		for (j = 0; j < ncRSCw2; ++j)
		{
			m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j];
		}

		nDataCwIndex += ncDataCw2;
		++nBlockNo;
	}

	m_nSymbleSize = m_nVersion * 4 + 17;

	FormatModule();

	return TRUE;
}
Esempio n. 4
0
int EncodeSourceData(const char* lpsSource, int ncLength, int nVerGroup)
{
	memset(m_nBlockLength, 0, sizeof(m_nBlockLength));
	int i, j;
	// Investigate whether continuing characters (bytes) which mode is what
	for (m_ncDataBlock = i = 0; i < ncLength; i++) {
		uint8_t byMode;
		if (IsNumeralData(lpsSource[i])) {
			byMode = QR_MODE_NUMERAL;
		} else if (IsAlphabetData(lpsSource[i])) {
			byMode = QR_MODE_ALPHABET;
		} else {
			byMode = QR_MODE_8BIT;
		}
		if (i == 0) {
			m_byBlockMode[0] = byMode;
		}
		if (m_byBlockMode[m_ncDataBlock] != byMode) {
			m_byBlockMode[++m_ncDataBlock] = byMode;
		}
		m_nBlockLength[m_ncDataBlock]++;
	}
	m_ncDataBlock++;

	// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
	// Linked by a sequence of conditional block alphanumeric mode and numeric mode block adjacent

	int ncSrcBits, ncDstBits; // The bit length of the block mode if you have over the original bit length and a single alphanumeric
	int nBlock = 0;

	while (nBlock < m_ncDataBlock - 1) {
		int ncJoinFront, ncJoinBehind; 		// Bit length when combined with 8-bit byte block mode before and after
		int nJoinPosition = 0; 		// Block the binding of 8-bit byte mode: combined with the previous -1 = 0 = do not bind, bind behind a =

		// Sort of - "digit alphanumeric" - "or alphanumeric numbers"
		if ((m_byBlockMode[nBlock] == QR_MODE_NUMERAL && m_byBlockMode[nBlock + 1] == QR_MODE_ALPHABET) ||
			(m_byBlockMode[nBlock] == QR_MODE_ALPHABET && m_byBlockMode[nBlock + 1] == QR_MODE_NUMERAL)) {

			// If you compare the bit length of alphanumeric characters and a single block mode over the original bit length
			ncSrcBits = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) +
						GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup);

			ncDstBits = GetBitLength(QR_MODE_ALPHABET, m_nBlockLength[nBlock] + m_nBlockLength[nBlock + 1], nVerGroup);

			if (ncSrcBits > ncDstBits) {
				// If there is an 8-bit byte block mode back and forth, check whether they favor the binding of
				if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT) {
					// There are 8-bit byte block mode before
					ncJoinFront = GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock - 1] + m_nBlockLength[nBlock], nVerGroup) +
								GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup);

					if (ncJoinFront > ncDstBits + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock - 1], nVerGroup)) {
						ncJoinFront = 0; // 8-bit byte and block mode does not bind
					}
				} else {
					ncJoinFront = 0;
				}

				if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT) {
					// There are 8-bit byte mode block behind
					ncJoinBehind = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) +
								GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock + 1] + m_nBlockLength[nBlock + 2], nVerGroup);

					if (ncJoinBehind > ncDstBits + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock + 2], nVerGroup)) {
						ncJoinBehind = 0; // 8-bit byte and block mode does not bind
					}
				} else {
					ncJoinBehind = 0;
				}

				if (ncJoinFront != 0 && ncJoinBehind != 0) {
					// If there is a 8-bit byte block mode has priority both before and after the way the data length is shorter
					nJoinPosition = (ncJoinFront < ncJoinBehind) ? -1 : 1;
				} else {
					nJoinPosition = (ncJoinFront != 0) ? -1 : ((ncJoinBehind != 0) ? 1 : 0);
				}

				if (nJoinPosition != 0) {
					// Block the binding of 8-bit byte mode
					if (nJoinPosition == -1) {
						m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock];

						// The subsequent shift
						for (i = nBlock; i < m_ncDataBlock - 1; i++) {
							m_byBlockMode[i] = m_byBlockMode[i + 1];
							m_nBlockLength[i] = m_nBlockLength[i + 1];
						}
					} else {
						m_byBlockMode[nBlock + 1] = QR_MODE_8BIT;
						m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2];

						// The subsequent shift
						for (i = nBlock + 2; i < m_ncDataBlock - 1; i++) {
							m_byBlockMode[i] = m_byBlockMode[i + 1];
							m_nBlockLength[i] = m_nBlockLength[i + 1];
						}
					}

					m_ncDataBlock--;
				} else {
				// Block mode integrated into a single alphanumeric string of numbers and alphanumeric

					if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_ALPHABET) {
						// Binding mode of the block followed by alphanumeric block attempts to join
						m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2];

						// The subsequent shift
						for (i = nBlock + 2; i < m_ncDataBlock - 1; i++) {
							m_byBlockMode[i] = m_byBlockMode[i + 1];
							m_nBlockLength[i] = m_nBlockLength[i + 1];
						}

						m_ncDataBlock--;
					}

					m_byBlockMode[nBlock] = QR_MODE_ALPHABET;
					m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1];

					// The subsequent shift
					for (i = nBlock + 1; i < m_ncDataBlock - 1; i++) {
						m_byBlockMode[i] = m_byBlockMode[i + 1];
						m_nBlockLength[i] = m_nBlockLength[i + 1];
					}

					m_ncDataBlock--;

					if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_ALPHABET) {

						// Combined mode of alphanumeric block before the block bound
						m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock];

						// The subsequent shift
						for (i = nBlock; i < m_ncDataBlock - 1; i++) {
							m_byBlockMode[i] = m_byBlockMode[i + 1];
							m_nBlockLength[i] = m_nBlockLength[i + 1];
						}

						m_ncDataBlock--;
					}
				}

				continue;
				// Re-examine the block of the current position
			}
		}

		nBlock++; // Investigate the next block
	}

	// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
	// 8-bit byte block mode over the short block mode to continuous

	nBlock = 0;

	while (nBlock < m_ncDataBlock - 1) {
		ncSrcBits = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup)
					+ GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup);

		ncDstBits = GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock] + m_nBlockLength[nBlock + 1], nVerGroup);

		// If there is a 8-bit byte block mode before, subtract the duplicate indicator minute
		if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT) {
			ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]);
		}

		// If there is a block behind the 8-bit byte mode, subtract the duplicate indicator minute
		if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT) {
			ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]);
		}

		if (ncSrcBits > ncDstBits) {
			if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT) {
				// 8-bit byte mode coupling block in front of the block to join
				m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock];

				// The subsequent shift
				for (i = nBlock; i < m_ncDataBlock - 1; i++) {
					m_byBlockMode[i] = m_byBlockMode[i + 1];
					m_nBlockLength[i] = m_nBlockLength[i + 1];
				}

				m_ncDataBlock--;
				nBlock--;
			}

			if (nBlock < m_ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT) {
				// 8-bit byte mode coupling block at the back of the block to join
				m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2];

				// The subsequent shift
				for (i = nBlock + 2; i < m_ncDataBlock - 1; i++) {
					m_byBlockMode[i] = m_byBlockMode[i + 1];
					m_nBlockLength[i] = m_nBlockLength[i + 1];
				}

				m_ncDataBlock--;
			}

			m_byBlockMode[nBlock] = QR_MODE_8BIT;
			m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1];

			// The subsequent shift
			for (i = nBlock + 1; i < m_ncDataBlock - 1; i++) {
				m_byBlockMode[i] = m_byBlockMode[i + 1];
				m_nBlockLength[i] = m_nBlockLength[i + 1];
			}

			m_ncDataBlock--;

			// Re-examination in front of the block bound
			if (nBlock >= 1) {
				nBlock--;
			}

			continue;
		}

		nBlock++;// Investigate the next block

	}

	// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
	// Mosquito bit array
	int ncComplete = 0;	// Data pre-processing counter

	uint16_t wBinCode;

	m_ncDataCodeWordBit = 0;// Bit counter processing unit

	memset(m_byDataCodeWord, 0, sizeof(m_byDataCodeWord));

	for (i = 0; i < m_ncDataBlock && m_ncDataCodeWordBit != -1; i++) {
		if (m_byBlockMode[i] == QR_MODE_NUMERAL) {
			// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
			// Numeric mode
			// Indicator (0001b)
			m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 1, 4);

			// Set number of characters
			m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)m_nBlockLength[i], nIndicatorLenNumeral[nVerGroup]);

			// Save the bit string
			for (j = 0; j < m_nBlockLength[i]; j += 3) {
				if (j < m_nBlockLength[i] - 2) {
					wBinCode = (uint16_t)(((lpsSource[ncComplete + j] - '0') * 100) +
									((lpsSource[ncComplete + j + 1] - '0') * 10) +
									(lpsSource[ncComplete + j + 2] - '0'));

					m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 10);
				} else
				if (j == m_nBlockLength[i] - 2) {

					// 2 bytes fraction
					wBinCode = (uint16_t)(((lpsSource[ncComplete + j] - '0') * 10) +
									(lpsSource[ncComplete + j + 1] - '0'));

					m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 7);
				} else
				if (j == m_nBlockLength[i] - 1) {

					// A fraction of bytes
					wBinCode = (uint16_t)(lpsSource[ncComplete + j] - '0');

					m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 4);
				}
			}

			ncComplete += m_nBlockLength[i];
		}

		else
		if (m_byBlockMode[i] == QR_MODE_ALPHABET) {
			// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
			// Alphanumeric mode
			// Mode indicator (0010b)
			m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 2, 4);

			// Set number of characters
			m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)m_nBlockLength[i], nIndicatorLenAlphabet[nVerGroup]);

			// Save the bit string
			for (j = 0; j < m_nBlockLength[i]; j += 2) {
				if (j < m_nBlockLength[i] - 1) {
					wBinCode = (uint16_t)((AlphabetToBinary(lpsSource[ncComplete + j]) * 45) +
									AlphabetToBinary(lpsSource[ncComplete + j + 1]));

					m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 11);
				} else {
					// A fraction of bytes
					wBinCode = (uint16_t)AlphabetToBinary(lpsSource[ncComplete + j]);

					m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, wBinCode, 6);
				}
			}

			ncComplete += m_nBlockLength[i];
		}

		else { // (m_byBlockMode[i] == QR_MODE_8BIT)
			// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
			// 8-bit byte mode

			// Mode indicator (0100b)
			m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, 4, 4);

			// Set number of characters
			m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)m_nBlockLength[i], nIndicatorLen8Bit[nVerGroup]);

			// Save the bit string
			for (j = 0; j < m_nBlockLength[i]; j++) {
				m_ncDataCodeWordBit = SetBitStream(m_ncDataCodeWordBit, (uint16_t)lpsSource[ncComplete + j], 8);
			}

			ncComplete += m_nBlockLength[i];
		}
	}

	return (m_ncDataCodeWordBit != -1);
}