public CDRepair(int finalSampleCount, int stride, int npar) { this.npar = npar; this.stride = stride; this.finalSampleCount = finalSampleCount; sampleCount = 0; galois = Galois16.instance; rs = new RsDecode16(npar, galois); //crc32 = new Crc32(); //crc = 0xffffffff; encodeGx = galois.makeEncodeGxLog(npar); laststride = stride + (finalSampleCount * 2) % stride; stridecount = (finalSampleCount * 2) / stride - 2; // minus one for leadin and one for leadout if ((finalSampleCount * 2 + stride - 1) / stride + npar > galois.Max) { throw new Exception("invalid stride"); } }
internal virtual int[] correctDataBlocks(int[] blocks) { int numSucceededCorrections = 0; int numCorrectionFailures = 0; int dataCapacity = qrCodeSymbol.DataCapacity; int[] dataBlocks = new int[dataCapacity]; int numErrorCollectionCode = qrCodeSymbol.NumErrorCollectionCode; int numRSBlocks = qrCodeSymbol.NumRSBlocks; int eccPerRSBlock = numErrorCollectionCode / numRSBlocks; if (numRSBlocks == 1) { RsDecode corrector = new RsDecode(eccPerRSBlock / 2); int ret = corrector.decode(blocks); if (ret > 0) { numSucceededCorrections += ret; } else if (ret < 0) { numCorrectionFailures++; } return(blocks); } else { //we have to interleave data blocks because symbol has 2 or more RS blocks int numLongerRSBlocks = dataCapacity % numRSBlocks; if (numLongerRSBlocks == 0) { //symbol has only 1 type of RS block int lengthRSBlock = dataCapacity / numRSBlocks; int[][] tmpArray = new int[numRSBlocks][]; for (int i = 0; i < numRSBlocks; i++) { tmpArray[i] = new int[lengthRSBlock]; } int[][] RSBlocks = tmpArray; //obtain RS blocks for (int i = 0; i < numRSBlocks; i++) { for (int j = 0; j < lengthRSBlock; j++) { RSBlocks[i][j] = blocks[j * numRSBlocks + i]; } RsDecode corrector = new RsDecode(eccPerRSBlock / 2); int ret = corrector.decode(RSBlocks[i]); if (ret > 0) { numSucceededCorrections += ret; } else if (ret < 0) { numCorrectionFailures++; } } //obtain only data part int p = 0; for (int i = 0; i < numRSBlocks; i++) { for (int j = 0; j < lengthRSBlock - eccPerRSBlock; j++) { dataBlocks[p++] = RSBlocks[i][j]; } } } else { //symbol has 2 types of RS blocks int lengthShorterRSBlock = dataCapacity / numRSBlocks; int lengthLongerRSBlock = dataCapacity / numRSBlocks + 1; int numShorterRSBlocks = numRSBlocks - numLongerRSBlocks; int[][] tmpArray2 = new int[numShorterRSBlocks][]; for (int i2 = 0; i2 < numShorterRSBlocks; i2++) { tmpArray2[i2] = new int[lengthShorterRSBlock]; } int[][] shorterRSBlocks = tmpArray2; int[][] tmpArray3 = new int[numLongerRSBlocks][]; for (int i3 = 0; i3 < numLongerRSBlocks; i3++) { tmpArray3[i3] = new int[lengthLongerRSBlock]; } int[][] longerRSBlocks = tmpArray3; for (int i = 0; i < numRSBlocks; 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] = blocks[j * numRSBlocks + i + mod]; } RsDecode corrector = new RsDecode(eccPerRSBlock / 2); int ret = corrector.decode(shorterRSBlocks[i]); if (ret > 0) { numSucceededCorrections += ret; } else if (ret < 0) { numCorrectionFailures++; } //ReedSolomon corrector = new ReedSolomon(shorterRSBlocks[i], eccPerRSBlock); //corrector.correct(); //numCorrections += corrector.NumCorrectedErrors; //correctionSucceeded = corrector.CorrectionSucceeded; } 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] = blocks[j * numRSBlocks + i - mod]; } RsDecode corrector = new RsDecode(eccPerRSBlock / 2); int ret = corrector.decode(longerRSBlocks[i - numShorterRSBlocks]); if (ret > 0) { numSucceededCorrections += ret; } else if (ret < 0) { numCorrectionFailures++; } //ReedSolomon corrector = new ReedSolomon(longerRSBlocks[i - numShorterRSBlocks], eccPerRSBlock); //corrector.correct(); //numCorrections += corrector.NumCorrectedErrors; //correctionSucceeded = corrector.CorrectionSucceeded; } } int p = 0; for (int i = 0; i < numRSBlocks; 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) { canvas.println(numSucceededCorrections.ToString() + " data errors corrected successfully."); } else { canvas.println("No errors found."); } numLastCorrectionFailures = numCorrectionFailures; //if (numCorrections > 0) // canvas.println(System.Convert.ToString(numCorrections) + " data errors corrected."); //else // canvas.println("No errors found."); //numLastCorrections = numCorrections; return(dataBlocks); } }
internal virtual int[] CorrectDataBlocks(int[] blocks) { int num1 = 0; int num2 = 0; int dataCapacity = this.qrCodeSymbol.DataCapacity; int[] numArray1 = new int[dataCapacity]; int errorCollectionCode = this.qrCodeSymbol.NumErrorCollectionCode; int numRsBlocks = this.qrCodeSymbol.NumRSBlocks; int num3 = errorCollectionCode / numRsBlocks; if (numRsBlocks == 1) { int num4 = new RsDecode(num3 / 2).Decode(blocks); if (num4 > 0) { int num5 = num1 + num4; } else if (num4 < 0) { int num6 = num2 + 1; } return(blocks); } int length1 = dataCapacity % numRsBlocks; if (length1 == 0) { int length2 = dataCapacity / numRsBlocks; int[][] numArray2 = new int[numRsBlocks][]; for (int index = 0; index < numRsBlocks; ++index) { numArray2[index] = new int[length2]; } int[][] numArray3 = numArray2; for (int index1 = 0; index1 < numRsBlocks; ++index1) { for (int index2 = 0; index2 < length2; ++index2) { numArray3[index1][index2] = blocks[index2 * numRsBlocks + index1]; } int num4 = new RsDecode(num3 / 2).Decode(numArray3[index1]); if (num4 > 0) { num1 += num4; } else if (num4 < 0) { ++num2; } } int num5 = 0; for (int index1 = 0; index1 < numRsBlocks; ++index1) { for (int index2 = 0; index2 < length2 - num3; ++index2) { numArray1[num5++] = numArray3[index1][index2]; } } } else { int length2 = dataCapacity / numRsBlocks; int length3 = dataCapacity / numRsBlocks + 1; int length4 = numRsBlocks - length1; int[][] numArray2 = new int[length4][]; for (int index = 0; index < length4; ++index) { numArray2[index] = new int[length2]; } int[][] numArray3 = numArray2; int[][] numArray4 = new int[length1][]; for (int index = 0; index < length1; ++index) { numArray4[index] = new int[length3]; } int[][] numArray5 = numArray4; for (int index1 = 0; index1 < numRsBlocks; ++index1) { if (index1 < length4) { int num4 = 0; for (int index2 = 0; index2 < length2; ++index2) { if (index2 == length2 - num3) { num4 = length1; } numArray3[index1][index2] = blocks[index2 * numRsBlocks + index1 + num4]; } int num5 = new RsDecode(num3 / 2).Decode(numArray3[index1]); if (num5 > 0) { num1 += num5; } else if (num5 < 0) { ++num2; } } else { int num4 = 0; for (int index2 = 0; index2 < length3; ++index2) { if (index2 == length2 - num3) { num4 = length4; } numArray5[index1 - length4][index2] = blocks[index2 * numRsBlocks + index1 - num4]; } int num5 = new RsDecode(num3 / 2).Decode(numArray5[index1 - length4]); if (num5 > 0) { num1 += num5; } else if (num5 < 0) { ++num2; } } } int num6 = 0; for (int index1 = 0; index1 < numRsBlocks; ++index1) { if (index1 < length4) { for (int index2 = 0; index2 < length2 - num3; ++index2) { numArray1[num6++] = numArray3[index1][index2]; } } else { for (int index2 = 0; index2 < length3 - num3; ++index2) { numArray1[num6++] = numArray5[index1 - length4][index2]; } } } } if (num1 > 0) { QRCodeDecoder.canvas.Print(Convert.ToString(num1) + " data errors corrected successfully."); } else { QRCodeDecoder.canvas.Print("No errors found."); } this.numLastCorrectionFailures = num2; return(numArray1); }