private byte[] removeECC(byte[] input) throws ReedSolomonException { if (input == null) { throw new IllegalArgumentException("The input to error correction code cannot be null"); } if (input.length > maxBytes) { throw new IllegalArgumentException("The input to error correction code plus error correction bytes cannot be longer than 256"); } int[] ints = new int[input.length]; for (int i = 0; i < ints.length; i++) { ints[i] = input[i] & 0xFF; } ReedSolomonDecoder d = new ReedSolomonDecoder(gf); d.decode(ints, errorCorrectionBytes); byte[] result = new byte[input.length - errorCorrectionBytes]; for (int i = 0; i < result.length; i++) { result[i] = (byte) ints[i]; } return result; }
/** * Corrects the parameter bits using Reed-Solomon algorithm. * * @param parameterData parameter bits * @param compact true if this is a compact Aztec code * @throws NotFoundException if the array contains too many errors */ private static int getCorrectedParameterData(long parameterData, boolean compact) throws NotFoundException { int numCodewords; int numDataCodewords; if (compact) { numCodewords = 7; numDataCodewords = 2; } else { numCodewords = 10; numDataCodewords = 4; } int numECCodewords = numCodewords - numDataCodewords; int[] parameterWords = new int[numCodewords]; for (int i = numCodewords - 1; i >= 0; --i) { parameterWords[i] = (int) parameterData & 0xF; parameterData >>= 4; } try { ReedSolomonDecoder rsDecoder = new ReedSolomonDecoder(GenericGF.AZTEC_PARAM); rsDecoder.decode(parameterWords, numECCodewords); } catch (ReedSolomonException ignored) { throw NotFoundException.getNotFoundInstance(); } // Toss the error correction. Just return the data as an integer int result = 0; for (int i = 0; i < numDataCodewords; i++) { result = (result << 4) + parameterWords[i]; } return result; }
private static int getCorrectedParameterData(long parameterData, boolean compact) throws NotFoundException { int numCodewords; int numDataCodewords; int i; if (compact) { numCodewords = 7; numDataCodewords = 2; } else { numCodewords = 10; numDataCodewords = 4; } int numECCodewords = numCodewords - numDataCodewords; int[] parameterWords = new int[numCodewords]; for (i = numCodewords - 1; i >= 0; i--) { parameterWords[i] = ((int) parameterData) & 15; parameterData >>= 4; } try { new ReedSolomonDecoder(GenericGF.AZTEC_PARAM).decode(parameterWords, numECCodewords); int result = 0; for (i = 0; i < numDataCodewords; i++) { result = (result << 4) + parameterWords[i]; } return result; } catch (ReedSolomonException e) { throw NotFoundException.getNotFoundInstance(); } }
/** Decode using Reed-Solomon error correction (with n bytes at the end of bits). */ public static Bits bitsReedSolomonDecode(final Bits bits, final int n) throws ReedSolomonException { int[] data = new Bits(bits.getBits(0, bits.size() - n * 8)).getBytes(); data = Arrays.copyOf(data, data.length + n); for (int i = 0; i < n; i++) { data[data.length - n + i] = (int) bits.getValue(bits.size() - n * 8 + i * 8, 8); } final ReedSolomonDecoder dec = new ReedSolomonDecoder(GenericGF.QR_CODE_FIELD_256); dec.decode(data, n); final Bits result = new Bits(); result.addBytes(Arrays.copyOf(data, data.length - n)); return result; }
/** * Corrects the parameter bits using Reed-Solomon algorithm. * * @param parameterData parameter bits * @param compact true if this is a compact Aztec code * @throws com.google.zxing.NotFoundException if the array contains too many errors */ private static int getCorrectedParameterData(long parameterData, boolean compact) throws NotFoundException { int numCodewords; int numDataCodewords; if (compact) { numCodewords = 7; numDataCodewords = 2; } else { numCodewords = 10; numDataCodewords = 4; } int numECCodewords = numCodewords - numDataCodewords; int[] parameterWords = new int[numCodewords]; for (int i = numCodewords - 1; i >= 0; --i) { parameterWords[i] = (int) parameterData & 0xF; parameterData >>= 4; } try { ReedSolomonDecoder rsDecoder = new ReedSolomonDecoder(GenericGF.AZTEC_PARAM); rsDecoder.decode(parameterWords, numECCodewords); } catch (ReedSolomonException ignored) { throw NotFoundException.getNotFoundInstance(); } // Toss the error correction. Just return the data as an integer int result = 0; for (int i = 0; i < numDataCodewords; i++) { result = (result << 4) + parameterWords[i]; } return result; }
/** Called when the samples have been updated. */ private static final void onGaydecki(final ReedSolomonDecoder pReedSolomonDecoder, final double[] pSamples, final double[] pConfidences, final int pSubsamples, final ChirpFactory.IListener pChirpListener) { // Calculate the Number of Symbols. final int lSymbols = (pSamples.length / pSubsamples); // Declare the String. String lAccumulation = ""; // Iterate the Samples whilst we're building up the string. for(int i = 0; i < lSymbols && (lAccumulation.length() != MainActivity.FACTORY_CHIRP.getEncodedLength()); i++) { // Fetch the Offset for the next Symbol. final int lOffset = (i * pSubsamples); // Detect the Chirp. final ChirpFactory.Result lResult = ChirpFactory.DETECTOR_CHIRP_MEAN.getSymbol(MainActivity.FACTORY_CHIRP, pSamples, pConfidences, lOffset, pSubsamples); // Is the Result valid? if(lResult.isValid()) { // Buffer the Result's data into the Accumulation. lAccumulation += lResult.getCharacter(); } } // Is the accumulated data long enough? if(lAccumulation.length() == MainActivity.FACTORY_CHIRP.getEncodedLength()) { // Declare the Packetized Representation. final int[] lPacketized = new int[MainActivity.FACTORY_CHIRP.getRange().getFrameLength()]; // Buffer the Header/Payload. for(int i = 0; i < MainActivity.FACTORY_CHIRP.getIdentifier().length() + MainActivity.FACTORY_CHIRP.getPayloadLength(); i++) { // Update the Packetized with the corresponding index value. lPacketized[i] = MainActivity.FACTORY_CHIRP.getRange().getCharacters().indexOf(lAccumulation.charAt(i)); } // Iterate the Error Symbols. for(int i = 0; i < MainActivity.FACTORY_CHIRP.getErrorLength(); i++) { // Update the Packetized with the corresponding index value. lPacketized[MainActivity.FACTORY_CHIRP.getRange().getFrameLength() - MainActivity.FACTORY_CHIRP.getErrorLength() + i] = MainActivity.FACTORY_CHIRP.getRange().getCharacters().indexOf(lAccumulation.charAt(MainActivity.FACTORY_CHIRP.getIdentifier().length() + MainActivity.FACTORY_CHIRP.getPayloadLength() + i)); } // Attempt to Reed/Solomon Decode. try { // Decode the Sample. pReedSolomonDecoder.decode(lPacketized, MainActivity.FACTORY_CHIRP.getErrorLength()); // Declare the search metric. boolean lIsValid = true; // Iterate the Identifier characters. for(int i = 0; i < MainActivity.FACTORY_CHIRP.getIdentifier().length(); i++) { // Update the search metric. lIsValid &= MainActivity.FACTORY_CHIRP.getIdentifier().charAt(i) == (MainActivity.FACTORY_CHIRP.getRange().getCharacters().charAt(lPacketized[i])); } // Is the message directed to us? if(lIsValid) { // Fetch the Message data. String lMessage = ""; // Iterate the Packet. for(int i = MainActivity.FACTORY_CHIRP.getIdentifier().length(); i < MainActivity.FACTORY_CHIRP.getIdentifier().length() + MainActivity.FACTORY_CHIRP.getPayloadLength(); i++) { // Accumulate the Message. lMessage += MainActivity.FACTORY_CHIRP.getRange().getCharacters().charAt(lPacketized[i]); } // Call the callback. pChirpListener.onChirp(lMessage); } } catch(final ReedSolomonException pReedSolomonException) { /* Do nothing; we're transmitting across a very lossy channel! */ } } }
private final ReedSolomonDecoder getReedSolomonDecoder() { return this.mReedSolomonDecoder; }
public Decoder() { rsDecoder = new ReedSolomonDecoder(GenericGF.QR_CODE_FIELD_256); }
public Decoder() { rsDecoder = new ReedSolomonDecoder(GenericGF.DATA_MATRIX_FIELD_256); }
public Decoder() { rsDecoder = new ReedSolomonDecoder(GenericGF.MAXICODE_FIELD_64); }
private boolean[] correctBits(boolean[] rawbits) throws FormatException { int codewordSize; GenericGF gf; if (this.ddata.getNbLayers() <= 2) { codewordSize = 6; gf = GenericGF.AZTEC_DATA_6; } else if (this.ddata.getNbLayers() <= 8) { codewordSize = 8; gf = GenericGF.AZTEC_DATA_8; } else if (this.ddata.getNbLayers() <= 22) { codewordSize = 10; gf = GenericGF.AZTEC_DATA_10; } else { codewordSize = 12; gf = GenericGF.AZTEC_DATA_12; } int numDataCodewords = this.ddata.getNbDatablocks(); int numCodewords = rawbits.length / codewordSize; if (numCodewords < numDataCodewords) { throw FormatException.getFormatInstance(); } int offset = rawbits.length % codewordSize; int numECCodewords = numCodewords - numDataCodewords; int[] dataWords = new int[numCodewords]; int i = 0; while (i < numCodewords) { dataWords[i] = readCode(rawbits, offset, codewordSize); i++; offset += codewordSize; } try { int dataWord; new ReedSolomonDecoder(gf).decode(dataWords, numECCodewords); int mask = (1 << codewordSize) - 1; int stuffedBits = 0; for (i = 0; i < numDataCodewords; i++) { dataWord = dataWords[i]; if (dataWord == 0 || dataWord == mask) { throw FormatException.getFormatInstance(); } if (dataWord == 1 || dataWord == mask - 1) { stuffedBits++; } } boolean[] correctedBits = new boolean[((numDataCodewords * codewordSize) - stuffedBits)]; int index = 0; for (i = 0; i < numDataCodewords; i++) { dataWord = dataWords[i]; if (dataWord == 1 || dataWord == mask - 1) { Arrays.fill(correctedBits, index, (index + codewordSize) - 1, dataWord > 1); index += codewordSize - 1; } else { int bit = codewordSize - 1; int index2 = index; while (bit >= 0) { index = index2 + 1; correctedBits[index2] = ((1 << bit) & dataWord) != 0; bit--; index2 = index; } index = index2; } } return correctedBits; } catch (ReedSolomonException ex) { throw FormatException.getFormatInstance(ex); } }