/// <summary> /// Decodes the specified detector result. /// </summary> /// <param name="detectorResult">The detector result.</param> /// <returns></returns> public DecoderResult decode(AztecDetectorResult detectorResult) { ddata = detectorResult; BitMatrix matrix = detectorResult.Bits; if (!ddata.isCompact()) { matrix = removeDashedLines(ddata.Bits); } bool[] rawbits = extractBits(matrix); if (rawbits == null) { return(null); } bool[] correctedBits = correctBits(rawbits); if (correctedBits == null) { return(null); } String result = getEncodedData(correctedBits); if (result == null) { return(null); } return(new DecoderResult(null, result, null, null)); }
/// <summary> /// performs RS error correction on an array of bits /// </summary> /// <param name="rawbits">The rawbits.</param> /// <returns>the corrected array</returns> /// <exception cref="FormatException">if the input contains too many errors</exception> private bool[] correctBits(bool[] rawbits) { GenericGF gf; if (ddata.getNbLayers() <= 2) { codewordSize = 6; gf = GenericGF.AZTEC_DATA_6; } else if (ddata.getNbLayers() <= 8) { codewordSize = 8; gf = GenericGF.AZTEC_DATA_8; } else if (ddata.getNbLayers() <= 22) { codewordSize = 10; gf = GenericGF.AZTEC_DATA_10; } else { codewordSize = 12; gf = GenericGF.AZTEC_DATA_12; } int numDataCodewords = ddata.getNbDatablocks(); int numECCodewords; int offset; if (ddata.isCompact()) { offset = NB_BITS_COMPACT[ddata.getNbLayers()] - numCodewords * codewordSize; numECCodewords = NB_DATABLOCK_COMPACT[ddata.getNbLayers()] - numDataCodewords; } else { offset = NB_BITS[ddata.getNbLayers()] - numCodewords * codewordSize; numECCodewords = NB_DATABLOCK[ddata.getNbLayers()] - numDataCodewords; } int[] dataWords = new int[numCodewords]; for (int i = 0; i < numCodewords; i++) { int flag = 1; for (int j = 1; j <= codewordSize; j++) { if (rawbits[codewordSize * i + codewordSize - j + offset]) { dataWords[i] += flag; } flag <<= 1; } //if (dataWords[i] >= flag) { // flag++; //} } var rsDecoder = new ReedSolomonDecoder(gf); if (!rsDecoder.decode(dataWords, numECCodewords)) { return(null); } offset = 0; invertedBitCount = 0; bool[] correctedBits = new bool[numDataCodewords * codewordSize]; for (int i = 0; i < numDataCodewords; i++) { bool seriesColor = false; int seriesCount = 0; int flag = 1 << (codewordSize - 1); for (int j = 0; j < codewordSize; j++) { bool color = (dataWords[i] & flag) == flag; if (seriesCount == codewordSize - 1) { if (color == seriesColor) { //bit must be inverted return(null); } seriesColor = false; seriesCount = 0; offset++; invertedBitCount++; } else { if (seriesColor == color) { seriesCount++; } else { seriesCount = 1; seriesColor = color; } correctedBits[i * codewordSize + j - offset] = color; } flag = (int)((uint)flag >> 1); // flag >>>= 1; } } return(correctedBits); }