Java Code Examples for com.google.zxing.ChecksumException#getChecksumInstance()

The following examples show how to use com.google.zxing.ChecksumException#getChecksumInstance() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Decoder.java    From ZXing-Orient with Apache License 2.0 6 votes vote down vote up
/**
 * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to
 * correct the errors in-place using Reed-Solomon error correction.</p>
 *
 * @param codewordBytes data and error correction codewords
 * @param numDataCodewords number of codewords that are data bytes
 * @throws ChecksumException if error correction fails
 */
private void correctErrors(byte[] codewordBytes, int numDataCodewords) throws ChecksumException {
  int numCodewords = codewordBytes.length;
  // First read into an array of ints
  int[] codewordsInts = new int[numCodewords];
  for (int i = 0; i < numCodewords; i++) {
    codewordsInts[i] = codewordBytes[i] & 0xFF;
  }
  int numECCodewords = codewordBytes.length - numDataCodewords;
  try {
    rsDecoder.decode(codewordsInts, numECCodewords);
  } catch (ReedSolomonException ignored) {
    throw ChecksumException.getChecksumInstance();
  }
  // Copy back into array of bytes -- only need to worry about the bytes that were data
  // We don't care about errors in the error-correction codewords
  for (int i = 0; i < numDataCodewords; i++) {
    codewordBytes[i] = (byte) codewordsInts[i];
  }
}
 
Example 2
Source File: Decoder.java    From weex with Apache License 2.0 6 votes vote down vote up
/**
 * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to
 * correct the errors in-place using Reed-Solomon error correction.</p>
 *
 * @param codewordBytes data and error correction codewords
 * @param numDataCodewords number of codewords that are data bytes
 * @throws ChecksumException if error correction fails
 */
private void correctErrors(byte[] codewordBytes, int numDataCodewords) throws ChecksumException {
  int numCodewords = codewordBytes.length;
  // First read into an array of ints
  int[] codewordsInts = new int[numCodewords];
  for (int i = 0; i < numCodewords; i++) {
    codewordsInts[i] = codewordBytes[i] & 0xFF;
  }
  int numECCodewords = codewordBytes.length - numDataCodewords;
  try {
    rsDecoder.decode(codewordsInts, numECCodewords);
  } catch (ReedSolomonException ignored) {
    throw ChecksumException.getChecksumInstance();
  }
  // Copy back into array of bytes -- only need to worry about the bytes that were data
  // We don't care about errors in the error-correction codewords
  for (int i = 0; i < numDataCodewords; i++) {
    codewordBytes[i] = (byte) codewordsInts[i];
  }
}
 
Example 3
Source File: Decoder.java    From analyzer-of-android-for-Apache-Weex with Apache License 2.0 6 votes vote down vote up
/**
 * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to
 * correct the errors in-place using Reed-Solomon error correction.</p>
 *
 * @param codewordBytes data and error correction codewords
 * @param numDataCodewords number of codewords that are data bytes
 * @throws ChecksumException if error correction fails
 */
private void correctErrors(byte[] codewordBytes, int numDataCodewords) throws ChecksumException {
  int numCodewords = codewordBytes.length;
  // First read into an array of ints
  int[] codewordsInts = new int[numCodewords];
  for (int i = 0; i < numCodewords; i++) {
    codewordsInts[i] = codewordBytes[i] & 0xFF;
  }
  int numECCodewords = codewordBytes.length - numDataCodewords;
  try {
    rsDecoder.decode(codewordsInts, numECCodewords);
  } catch (ReedSolomonException ignored) {
    throw ChecksumException.getChecksumInstance();
  }
  // Copy back into array of bytes -- only need to worry about the bytes that were data
  // We don't care about errors in the error-correction codewords
  for (int i = 0; i < numDataCodewords; i++) {
    codewordBytes[i] = (byte) codewordsInts[i];
  }
}
 
Example 4
Source File: ErrorCorrection.java    From analyzer-of-android-for-Apache-Weex with Apache License 2.0 6 votes vote down vote up
private int[] findErrorLocations(ModulusPoly errorLocator) throws ChecksumException {
  // This is a direct application of Chien's search
  int numErrors = errorLocator.getDegree();
  int[] result = new int[numErrors];
  int e = 0;
  for (int i = 1; i < field.getSize() && e < numErrors; i++) {
    if (errorLocator.evaluateAt(i) == 0) {
      result[e] = field.inverse(i);
      e++;
    }
  }
  if (e != numErrors) {
    throw ChecksumException.getChecksumInstance();
  }
  return result;
}
 
Example 5
Source File: Decoder.java    From ZXing-Orient with Apache License 2.0 6 votes vote down vote up
/**
 * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to
 * correct the errors in-place using Reed-Solomon error correction.</p>
 *
 * @param codewordBytes data and error correction codewords
 * @param numDataCodewords number of codewords that are data bytes
 * @throws ChecksumException if error correction fails
 */
private void correctErrors(byte[] codewordBytes, int numDataCodewords) throws ChecksumException {
  int numCodewords = codewordBytes.length;
  // First read into an array of ints
  int[] codewordsInts = new int[numCodewords];
  for (int i = 0; i < numCodewords; i++) {
    codewordsInts[i] = codewordBytes[i] & 0xFF;
  }
  int numECCodewords = codewordBytes.length - numDataCodewords;
  try {
    rsDecoder.decode(codewordsInts, numECCodewords);
  } catch (ReedSolomonException ignored) {
    throw ChecksumException.getChecksumInstance();
  }
  // Copy back into array of bytes -- only need to worry about the bytes that were data
  // We don't care about errors in the error-correction codewords
  for (int i = 0; i < numDataCodewords; i++) {
    codewordBytes[i] = (byte) codewordsInts[i];
  }
}
 
Example 6
Source File: Decoder.java    From ScreenCapture with MIT License 6 votes vote down vote up
/**
 * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to
 * correct the errors in-place using Reed-Solomon error correction.</p>
 *
 * @param codewordBytes data and error correction codewords
 * @param numDataCodewords number of codewords that are data bytes
 * @throws ChecksumException if error correction fails
 */
private void correctErrors(byte[] codewordBytes, int numDataCodewords) throws ChecksumException {
  int numCodewords = codewordBytes.length;
  // First read into an array of ints
  int[] codewordsInts = new int[numCodewords];
  for (int i = 0; i < numCodewords; i++) {
    codewordsInts[i] = codewordBytes[i] & 0xFF;
  }
  try {
    rsDecoder.decode(codewordsInts, codewordBytes.length - numDataCodewords);
  } catch (ReedSolomonException ignored) {
    throw ChecksumException.getChecksumInstance();
  }
  // Copy back into array of bytes -- only need to worry about the bytes that were data
  // We don't care about errors in the error-correction codewords
  for (int i = 0; i < numDataCodewords; i++) {
    codewordBytes[i] = (byte) codewordsInts[i];
  }
}
 
Example 7
Source File: Decoder.java    From analyzer-of-android-for-Apache-Weex with Apache License 2.0 6 votes vote down vote up
/**
 * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to
 * correct the errors in-place using Reed-Solomon error correction.</p>
 *
 * @param codewordBytes data and error correction codewords
 * @param numDataCodewords number of codewords that are data bytes
 * @throws ChecksumException if error correction fails
 */
private void correctErrors(byte[] codewordBytes, int numDataCodewords) throws ChecksumException {
  int numCodewords = codewordBytes.length;
  // First read into an array of ints
  int[] codewordsInts = new int[numCodewords];
  for (int i = 0; i < numCodewords; i++) {
    codewordsInts[i] = codewordBytes[i] & 0xFF;
  }
  int numECCodewords = codewordBytes.length - numDataCodewords;
  try {
    rsDecoder.decode(codewordsInts, numECCodewords);
  } catch (ReedSolomonException ignored) {
    throw ChecksumException.getChecksumInstance();
  }
  // Copy back into array of bytes -- only need to worry about the bytes that were data
  // We don't care about errors in the error-correction codewords
  for (int i = 0; i < numDataCodewords; i++) {
    codewordBytes[i] = (byte) codewordsInts[i];
  }
}
 
Example 8
Source File: Decoder.java    From Tesseract-OCR-Scanner with Apache License 2.0 6 votes vote down vote up
/**
 * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to
 * correct the errors in-place using Reed-Solomon error correction.</p>
 *
 * @param codewordBytes data and error correction codewords
 * @param numDataCodewords number of codewords that are data bytes
 * @throws ChecksumException if error correction fails
 */
private void correctErrors(byte[] codewordBytes, int numDataCodewords) throws ChecksumException {
  int numCodewords = codewordBytes.length;
  // First read into an array of ints
  int[] codewordsInts = new int[numCodewords];
  for (int i = 0; i < numCodewords; i++) {
    codewordsInts[i] = codewordBytes[i] & 0xFF;
  }
  try {
    rsDecoder.decode(codewordsInts, codewordBytes.length - numDataCodewords);
  } catch (ReedSolomonException ignored) {
    throw ChecksumException.getChecksumInstance();
  }
  // Copy back into array of bytes -- only need to worry about the bytes that were data
  // We don't care about errors in the error-correction codewords
  for (int i = 0; i < numDataCodewords; i++) {
    codewordBytes[i] = (byte) codewordsInts[i];
  }
}
 
Example 9
Source File: PDF417ScanningDecoder.java    From ZXing-Orient with Apache License 2.0 5 votes vote down vote up
/**
 * This method deals with the fact, that the decoding process doesn't always yield a single most likely value. The
 * current error correction implementation doesn't deal with erasures very well, so it's better to provide a value
 * for these ambiguous codewords instead of treating it as an erasure. The problem is that we don't know which of
 * the ambiguous values to choose. We try decode using the first value, and if that fails, we use another of the
 * ambiguous values and try to decode again. This usually only happens on very hard to read and decode barcodes,
 * so decoding the normal barcodes is not affected by this. 
 *
 * @param erasureArray contains the indexes of erasures
 * @param ambiguousIndexes array with the indexes that have more than one most likely value
 * @param ambiguousIndexValues two dimensional array that contains the ambiguous values. The first dimension must
 * be the same length as the ambiguousIndexes array
 */
private static DecoderResult createDecoderResultFromAmbiguousValues(int ecLevel,
                                                                    int[] codewords,
                                                                    int[] erasureArray,
                                                                    int[] ambiguousIndexes,
                                                                    int[][] ambiguousIndexValues)
    throws FormatException, ChecksumException {
  int[] ambiguousIndexCount = new int[ambiguousIndexes.length];

  int tries = 100;
  while (tries-- > 0) {
    for (int i = 0; i < ambiguousIndexCount.length; i++) {
      codewords[ambiguousIndexes[i]] = ambiguousIndexValues[i][ambiguousIndexCount[i]];
    }
    try {
      return decodeCodewords(codewords, ecLevel, erasureArray);
    } catch (ChecksumException ignored) {
      //
    }
    if (ambiguousIndexCount.length == 0) {
      throw ChecksumException.getChecksumInstance();
    }
    for (int i = 0; i < ambiguousIndexCount.length; i++) {
      if (ambiguousIndexCount[i] < ambiguousIndexValues[i].length - 1) {
        ambiguousIndexCount[i]++;
        break;
      } else {
        ambiguousIndexCount[i] = 0;
        if (i == ambiguousIndexCount.length - 1) {
          throw ChecksumException.getChecksumInstance();
        }
      }
    }
  }
  throw ChecksumException.getChecksumInstance();
}
 
Example 10
Source File: PDF417ScanningDecoder.java    From ZXing-Orient with Apache License 2.0 5 votes vote down vote up
/**
 * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to
 * correct the errors in-place.</p>
 *
 * @param codewords   data and error correction codewords
 * @param erasures positions of any known erasures
 * @param numECCodewords number of error correction codewords that are available in codewords
 * @throws ChecksumException if error correction fails
 */
private static int correctErrors(int[] codewords, int[] erasures, int numECCodewords) throws ChecksumException {
  if (erasures != null &&
      erasures.length > numECCodewords / 2 + MAX_ERRORS ||
      numECCodewords < 0 ||
      numECCodewords > MAX_EC_CODEWORDS) {
    // Too many errors or EC Codewords is corrupted
    throw ChecksumException.getChecksumInstance();
  }
  return errorCorrection.decode(codewords, numECCodewords, erasures);
}
 
Example 11
Source File: Decoder.java    From analyzer-of-android-for-Apache-Weex with Apache License 2.0 5 votes vote down vote up
private void correctErrors(byte[] codewordBytes,
                           int start,
                           int dataCodewords,
                           int ecCodewords,
                           int mode) throws ChecksumException {
  int codewords = dataCodewords + ecCodewords;

  // in EVEN or ODD mode only half the codewords
  int divisor = mode == ALL ? 1 : 2;

  // First read into an array of ints
  int[] codewordsInts = new int[codewords / divisor];
  for (int i = 0; i < codewords; i++) {
    if ((mode == ALL) || (i % 2 == (mode - 1))) {
      codewordsInts[i / divisor] = codewordBytes[i + start] & 0xFF;
    }
  }
  try {
    rsDecoder.decode(codewordsInts, ecCodewords / divisor);
  } catch (ReedSolomonException ignored) {
    throw ChecksumException.getChecksumInstance();
  }
  // Copy back into array of bytes -- only need to worry about the bytes that were data
  // We don't care about errors in the error-correction codewords
  for (int i = 0; i < dataCodewords; i++) {
    if ((mode == ALL) || (i % 2 == (mode - 1))) {
      codewordBytes[i + start] = (byte) codewordsInts[i / divisor];
    }
  }
}
 
Example 12
Source File: PDF417ScanningDecoder.java    From weex with Apache License 2.0 5 votes vote down vote up
/**
 * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to
 * correct the errors in-place.</p>
 *
 * @param codewords   data and error correction codewords
 * @param erasures positions of any known erasures
 * @param numECCodewords number of error correction codewords that are available in codewords
 * @throws ChecksumException if error correction fails
 */
private static int correctErrors(int[] codewords, int[] erasures, int numECCodewords) throws ChecksumException {
  if (erasures != null &&
      erasures.length > numECCodewords / 2 + MAX_ERRORS ||
      numECCodewords < 0 ||
      numECCodewords > MAX_EC_CODEWORDS) {
    // Too many errors or EC Codewords is corrupted
    throw ChecksumException.getChecksumInstance();
  }
  return errorCorrection.decode(codewords, numECCodewords, erasures);
}
 
Example 13
Source File: Code93Reader.java    From QrCodeScanner with GNU General Public License v3.0 5 votes vote down vote up
private static void checkOneChecksum(CharSequence result, int checkPosition, int weightMax)
    throws ChecksumException {
  int weight = 1;
  int total = 0;
  for (int i = checkPosition - 1; i >= 0; i--) {
    total += weight * ALPHABET_STRING.indexOf(result.charAt(i));
    if (++weight > weightMax) {
      weight = 1;
    }
  }
  if (result.charAt(checkPosition) != ALPHABET[total % 47]) {
    throw ChecksumException.getChecksumInstance();
  }
}
 
Example 14
Source File: Decoder.java    From ZXing-Orient with Apache License 2.0 5 votes vote down vote up
private void correctErrors(byte[] codewordBytes,
                           int start,
                           int dataCodewords,
                           int ecCodewords,
                           int mode) throws ChecksumException {
  int codewords = dataCodewords + ecCodewords;

  // in EVEN or ODD mode only half the codewords
  int divisor = mode == ALL ? 1 : 2;

  // First read into an array of ints
  int[] codewordsInts = new int[codewords / divisor];
  for (int i = 0; i < codewords; i++) {
    if ((mode == ALL) || (i % 2 == (mode - 1))) {
      codewordsInts[i / divisor] = codewordBytes[i + start] & 0xFF;
    }
  }
  try {
    rsDecoder.decode(codewordsInts, ecCodewords / divisor);
  } catch (ReedSolomonException ignored) {
    throw ChecksumException.getChecksumInstance();
  }
  // Copy back into array of bytes -- only need to worry about the bytes that were data
  // We don't care about errors in the error-correction codewords
  for (int i = 0; i < dataCodewords; i++) {
    if ((mode == ALL) || (i % 2 == (mode - 1))) {
      codewordBytes[i + start] = (byte) codewordsInts[i / divisor];
    }
  }
}
 
Example 15
Source File: PDF417ScanningDecoder.java    From analyzer-of-android-for-Apache-Weex with Apache License 2.0 5 votes vote down vote up
/**
 * This method deals with the fact, that the decoding process doesn't always yield a single most likely value. The
 * current error correction implementation doesn't deal with erasures very well, so it's better to provide a value
 * for these ambiguous codewords instead of treating it as an erasure. The problem is that we don't know which of
 * the ambiguous values to choose. We try decode using the first value, and if that fails, we use another of the
 * ambiguous values and try to decode again. This usually only happens on very hard to read and decode barcodes,
 * so decoding the normal barcodes is not affected by this. 
 *
 * @param erasureArray contains the indexes of erasures
 * @param ambiguousIndexes array with the indexes that have more than one most likely value
 * @param ambiguousIndexValues two dimensional array that contains the ambiguous values. The first dimension must
 * be the same length as the ambiguousIndexes array
 */
private static DecoderResult createDecoderResultFromAmbiguousValues(int ecLevel,
                                                                    int[] codewords,
                                                                    int[] erasureArray,
                                                                    int[] ambiguousIndexes,
                                                                    int[][] ambiguousIndexValues)
    throws FormatException, ChecksumException {
  int[] ambiguousIndexCount = new int[ambiguousIndexes.length];

  int tries = 100;
  while (tries-- > 0) {
    for (int i = 0; i < ambiguousIndexCount.length; i++) {
      codewords[ambiguousIndexes[i]] = ambiguousIndexValues[i][ambiguousIndexCount[i]];
    }
    try {
      return decodeCodewords(codewords, ecLevel, erasureArray);
    } catch (ChecksumException ignored) {
      //
    }
    if (ambiguousIndexCount.length == 0) {
      throw ChecksumException.getChecksumInstance();
    }
    for (int i = 0; i < ambiguousIndexCount.length; i++) {
      if (ambiguousIndexCount[i] < ambiguousIndexValues[i].length - 1) {
        ambiguousIndexCount[i]++;
        break;
      } else {
        ambiguousIndexCount[i] = 0;
        if (i == ambiguousIndexCount.length - 1) {
          throw ChecksumException.getChecksumInstance();
        }
      }
    }
  }
  throw ChecksumException.getChecksumInstance();
}
 
Example 16
Source File: PDF417ScanningDecoder.java    From analyzer-of-android-for-Apache-Weex with Apache License 2.0 5 votes vote down vote up
/**
 * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to
 * correct the errors in-place.</p>
 *
 * @param codewords   data and error correction codewords
 * @param erasures positions of any known erasures
 * @param numECCodewords number of error correction codewords that are available in codewords
 * @throws ChecksumException if error correction fails
 */
private static int correctErrors(int[] codewords, int[] erasures, int numECCodewords) throws ChecksumException {
  if (erasures != null &&
      erasures.length > numECCodewords / 2 + MAX_ERRORS ||
      numECCodewords < 0 ||
      numECCodewords > MAX_EC_CODEWORDS) {
    // Too many errors or EC Codewords is corrupted
    throw ChecksumException.getChecksumInstance();
  }
  return errorCorrection.decode(codewords, numECCodewords, erasures);
}
 
Example 17
Source File: Code93Reader.java    From Tesseract-OCR-Scanner with Apache License 2.0 5 votes vote down vote up
private static void checkOneChecksum(CharSequence result, int checkPosition, int weightMax)
    throws ChecksumException {
  int weight = 1;
  int total = 0;
  for (int i = checkPosition - 1; i >= 0; i--) {
    total += weight * ALPHABET_STRING.indexOf(result.charAt(i));
    if (++weight > weightMax) {
      weight = 1;
    }
  }
  if (result.charAt(checkPosition) != ALPHABET[total % 47]) {
    throw ChecksumException.getChecksumInstance();
  }
}
 
Example 18
Source File: Decoder.java    From weex with Apache License 2.0 5 votes vote down vote up
private void correctErrors(byte[] codewordBytes,
                           int start,
                           int dataCodewords,
                           int ecCodewords,
                           int mode) throws ChecksumException {
  int codewords = dataCodewords + ecCodewords;

  // in EVEN or ODD mode only half the codewords
  int divisor = mode == ALL ? 1 : 2;

  // First read into an array of ints
  int[] codewordsInts = new int[codewords / divisor];
  for (int i = 0; i < codewords; i++) {
    if ((mode == ALL) || (i % 2 == (mode - 1))) {
      codewordsInts[i / divisor] = codewordBytes[i + start] & 0xFF;
    }
  }
  try {
    rsDecoder.decode(codewordsInts, ecCodewords / divisor);
  } catch (ReedSolomonException ignored) {
    throw ChecksumException.getChecksumInstance();
  }
  // Copy back into array of bytes -- only need to worry about the bytes that were data
  // We don't care about errors in the error-correction codewords
  for (int i = 0; i < dataCodewords; i++) {
    if ((mode == ALL) || (i % 2 == (mode - 1))) {
      codewordBytes[i + start] = (byte) codewordsInts[i / divisor];
    }
  }
}
 
Example 19
Source File: ErrorCorrection.java    From weex with Apache License 2.0 4 votes vote down vote up
/**
 * @param received received codewords
 * @param numECCodewords number of those codewords used for EC
 * @param erasures location of erasures
 * @return number of errors
 * @throws ChecksumException if errors cannot be corrected, maybe because of too many errors
 */
public int decode(int[] received,
                  int numECCodewords,
                  int[] erasures) throws ChecksumException {

  ModulusPoly poly = new ModulusPoly(field, received);
  int[] S = new int[numECCodewords];
  boolean error = false;
  for (int i = numECCodewords; i > 0; i--) {
    int eval = poly.evaluateAt(field.exp(i));
    S[numECCodewords - i] = eval;
    if (eval != 0) {
      error = true;
    }
  }

  if (!error) {
    return 0;
  }

  ModulusPoly knownErrors = field.getOne();
  if (erasures != null) {
    for (int erasure : erasures) {
      int b = field.exp(received.length - 1 - erasure);
      // Add (1 - bx) term:
      ModulusPoly term = new ModulusPoly(field, new int[]{field.subtract(0, b), 1});
      knownErrors = knownErrors.multiply(term);
    }
  }

  ModulusPoly syndrome = new ModulusPoly(field, S);
  //syndrome = syndrome.multiply(knownErrors);

  ModulusPoly[] sigmaOmega =
      runEuclideanAlgorithm(field.buildMonomial(numECCodewords, 1), syndrome, numECCodewords);
  ModulusPoly sigma = sigmaOmega[0];
  ModulusPoly omega = sigmaOmega[1];

  //sigma = sigma.multiply(knownErrors);

  int[] errorLocations = findErrorLocations(sigma);
  int[] errorMagnitudes = findErrorMagnitudes(omega, sigma, errorLocations);

  for (int i = 0; i < errorLocations.length; i++) {
    int position = received.length - 1 - field.log(errorLocations[i]);
    if (position < 0) {
      throw ChecksumException.getChecksumInstance();
    }
    received[position] = field.subtract(received[position], errorMagnitudes[i]);
  }
  return errorLocations.length;
}
 
Example 20
Source File: ErrorCorrection.java    From analyzer-of-android-for-Apache-Weex with Apache License 2.0 4 votes vote down vote up
/**
 * @param received received codewords
 * @param numECCodewords number of those codewords used for EC
 * @param erasures location of erasures
 * @return number of errors
 * @throws ChecksumException if errors cannot be corrected, maybe because of too many errors
 */
public int decode(int[] received,
                  int numECCodewords,
                  int[] erasures) throws ChecksumException {

  ModulusPoly poly = new ModulusPoly(field, received);
  int[] S = new int[numECCodewords];
  boolean error = false;
  for (int i = numECCodewords; i > 0; i--) {
    int eval = poly.evaluateAt(field.exp(i));
    S[numECCodewords - i] = eval;
    if (eval != 0) {
      error = true;
    }
  }

  if (!error) {
    return 0;
  }

  ModulusPoly knownErrors = field.getOne();
  if (erasures != null) {
    for (int erasure : erasures) {
      int b = field.exp(received.length - 1 - erasure);
      // Add (1 - bx) term:
      ModulusPoly term = new ModulusPoly(field, new int[]{field.subtract(0, b), 1});
      knownErrors = knownErrors.multiply(term);
    }
  }

  ModulusPoly syndrome = new ModulusPoly(field, S);
  //syndrome = syndrome.multiply(knownErrors);

  ModulusPoly[] sigmaOmega =
      runEuclideanAlgorithm(field.buildMonomial(numECCodewords, 1), syndrome, numECCodewords);
  ModulusPoly sigma = sigmaOmega[0];
  ModulusPoly omega = sigmaOmega[1];

  //sigma = sigma.multiply(knownErrors);

  int[] errorLocations = findErrorLocations(sigma);
  int[] errorMagnitudes = findErrorMagnitudes(omega, sigma, errorLocations);

  for (int i = 0; i < errorLocations.length; i++) {
    int position = received.length - 1 - field.log(errorLocations[i]);
    if (position < 0) {
      throw ChecksumException.getChecksumInstance();
    }
    received[position] = field.subtract(received[position], errorMagnitudes[i]);
  }
  return errorLocations.length;
}