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); }
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; }
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; }
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); }