/** * \brief Convert fitted Data Matrix region into a decoded message * \param dec * \param reg * \param fix * \return Decoded message */ extern DmtxMessage * dmtxDecodeMatrixRegion(DmtxDecode *dec, DmtxRegion *reg, int fix) { DmtxMessage *msg; DmtxVector2 topLeft, topRight, bottomLeft, bottomRight; DmtxPixelLoc pxTopLeft, pxTopRight, pxBottomLeft, pxBottomRight; msg = dmtxMessageCreate(reg->sizeIdx, DmtxFormatMatrix); if(msg == NULL) return NULL; if(PopulateArrayFromMatrix(dec, reg, msg) != DmtxPass) { dmtxMessageDestroy(&msg); return NULL; } /* maybe place remaining logic into new dmtxDecodePopulatedArray() function so other people can pass in their own arrays */ ModulePlacementEcc200(msg->array, msg->code, reg->sizeIdx, DmtxModuleOnRed | DmtxModuleOnGreen | DmtxModuleOnBlue); if(RsDecode(msg->code, reg->sizeIdx, fix) == DmtxFail) { dmtxMessageDestroy(&msg); return NULL; } topLeft.X = bottomLeft.X = topLeft.Y = topRight.Y = -0.1; topRight.X = bottomRight.X = bottomLeft.Y = bottomRight.Y = 1.1; dmtxMatrix3VMultiplyBy(&topLeft, reg->fit2raw); dmtxMatrix3VMultiplyBy(&topRight, reg->fit2raw); dmtxMatrix3VMultiplyBy(&bottomLeft, reg->fit2raw); dmtxMatrix3VMultiplyBy(&bottomRight, reg->fit2raw); pxTopLeft.X = (int)(0.5 + topLeft.X); pxTopLeft.Y = (int)(0.5 + topLeft.Y); pxBottomLeft.X = (int)(0.5 + bottomLeft.X); pxBottomLeft.Y = (int)(0.5 + bottomLeft.Y); pxTopRight.X = (int)(0.5 + topRight.X); pxTopRight.Y = (int)(0.5 + topRight.Y); pxBottomRight.X = (int)(0.5 + bottomRight.X); pxBottomRight.Y = (int)(0.5 + bottomRight.Y); CacheFillQuad(dec, pxTopLeft, pxTopRight, pxBottomRight, pxBottomLeft); DecodeDataStream(msg, reg->sizeIdx, NULL); return msg; }
//纠错 void ContentDecoder::CorrectDataBlocks() { int i,j,k; int numSucceededCorrections = 0; int numCorrectionFailures = 0; m_ncAllCodeWord=QR_VersonInfo[m_nVersion].ncAllCodeWord;//int dataCapacity = qrCodeSymbol.getDataCapacity(); m_ncDataCodeWord = QR_VersonInfo[m_nVersion].ncDataCodeWord[m_nLevel];//... m_ncRSCodeWord=m_ncAllCodeWord-m_ncDataCodeWord;//int numErrorCollectionCode = qrCodeSymbol.getNumErrorCollectionCode(); int ncBlock1 = QR_VersonInfo[m_nVersion].RS_BlockInfo1[m_nLevel].ncRSBlock;//... int ncBlock2 = QR_VersonInfo[m_nVersion].RS_BlockInfo2[m_nLevel].ncRSBlock;//... int ncBlockSum = ncBlock1 + ncBlock2;//int numRSBlocks = qrCodeSymbol.getNumRSBlocks(); int eccPerRSBlock = m_ncRSCodeWord / ncBlockSum; if (ncBlockSum == 1) { RsDecode corrector = RsDecode(eccPerRSBlock / 2); int ret = corrector.decode(m_byAllCodeWord,m_ncAllCodeWord); if (ret > 0) numSucceededCorrections += ret; else if (ret < 0) numCorrectionFailures++; for(i=0;i<m_ncDataCodeWord;i++) m_byDataCodeWord[i]=m_byAllCodeWord[i]; } else { //interleave data blocks because symbol has 2 or more RS blocks int * dataBlocks = new int[m_ncAllCodeWord]; memset(dataBlocks, 0, m_ncAllCodeWord); int numLongerRSBlocks = m_ncAllCodeWord % ncBlockSum; if (numLongerRSBlocks == 0) { //symbol has only 1 type of RS block int lengthRSBlock = m_ncAllCodeWord / ncBlockSum; unsigned char ** RSBlocks = new unsigned char * [ncBlockSum];//... for(k=0;k<ncBlockSum;k++) { RSBlocks[k] = new unsigned char [lengthRSBlock]; memset(RSBlocks[k], 0, lengthRSBlock); }//int[][] RSBlocks = new int[ncBlockSum][lengthRSBlock]; //obtain RS blocks for (i = 0; i < ncBlockSum; i++) { for (j = 0; j < lengthRSBlock; j++) { RSBlocks[i][j] = m_byAllCodeWord[j * ncBlockSum + i]; } RsDecode corrector = RsDecode(eccPerRSBlock / 2); int ret = corrector.decode(RSBlocks[i],lengthRSBlock); if (ret > 0) numSucceededCorrections += ret; else if (ret < 0) numCorrectionFailures++; } //obtain only data part int p = 0; for (i = 0; i < ncBlockSum; i++) { for (j = 0; j < lengthRSBlock - eccPerRSBlock; j++) { dataBlocks[p++] = RSBlocks[i][j]; } } } else { //symbol has 2 types of RS blocks int lengthShorterRSBlock = m_ncAllCodeWord / ncBlockSum; int lengthLongerRSBlock = m_ncAllCodeWord / ncBlockSum + 1; int numShorterRSBlocks = ncBlockSum - numLongerRSBlocks; unsigned char ** shorterRSBlocks = new unsigned char * [numShorterRSBlocks];//... for(k=0;k<numShorterRSBlocks;k++) { shorterRSBlocks[k] = new unsigned char [lengthShorterRSBlock]; memset(shorterRSBlocks[k], 0, lengthShorterRSBlock); }//int[][] shorterRSBlocks = new int[numShorterRSBlocks][lengthShorterRSBlock]; unsigned char ** longerRSBlocks = new unsigned char * [numLongerRSBlocks];//... for(k=0;k<numLongerRSBlocks;k++) { longerRSBlocks[k] = new unsigned char [lengthLongerRSBlock]; memset(longerRSBlocks[k], 0, lengthLongerRSBlock); }//int[][] longerRSBlocks = new int[numLongerRSBlocks][lengthLongerRSBlock]; for (int i = 0; i < ncBlockSum; i++) { if (i < numShorterRSBlocks) { //get shorter RS Block(s) int mod = 0; for (int j = 0; j < lengthShorterRSBlock; j++) { if (j == lengthShorterRSBlock - eccPerRSBlock) mod = numLongerRSBlocks; shorterRSBlocks[i][j] = m_byAllCodeWord[j * ncBlockSum + i + mod]; } //canvas.println("eccPerRSBlock(shorter)=" + eccPerRSBlock ); RsDecode corrector = RsDecode(eccPerRSBlock / 2); int ret = corrector.decode(shorterRSBlocks[i],lengthShorterRSBlock); if (ret > 0) numSucceededCorrections += ret; else if (ret < 0) numCorrectionFailures++; } else { //get longer RS Blocks int mod = 0; for (int j = 0; j < lengthLongerRSBlock; j++) { if (j == lengthShorterRSBlock - eccPerRSBlock) mod = numShorterRSBlocks; longerRSBlocks[i - numShorterRSBlocks][j] = m_byAllCodeWord[j * ncBlockSum + i - mod]; } //canvas.println("eccPerRSBlock(longer)=" + eccPerRSBlock ); RsDecode corrector = RsDecode(eccPerRSBlock / 2); int ret = corrector.decode(longerRSBlocks[i-numShorterRSBlocks],lengthLongerRSBlock); if (ret > 0) numSucceededCorrections += ret; else if (ret < 0) numCorrectionFailures++; } } int p = 0; for (int i = 0; i < ncBlockSum; i++) { if (i < numShorterRSBlocks) { for (int j = 0; j < lengthShorterRSBlock - eccPerRSBlock; j++) { dataBlocks[p++] = shorterRSBlocks[i][j]; } } else { for (int j = 0; j < lengthLongerRSBlock - eccPerRSBlock; j++) { dataBlocks[p++] = longerRSBlocks[i - numShorterRSBlocks][j]; } } } } /*if (numSucceededCorrections > 0) { char s[10]; itoa(numSucceededCorrections,s,10); AfxMessageBox(s);//" data errors corrected successfully."numSucceededCorrections } else AfxMessageBox("No errors found.");*/ for(i=0;i<m_ncDataCodeWord;i++) m_byDataCodeWord[i]=dataBlocks[i]; } }