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 #2
0
 /**
  * Given data and error-correction codewords received, possibly corrupted by errors, attempts to
  * correct the errors in-place using Reed-Solomon error correction.
  *
  * @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 #3
0
  @Override
  public Result decodeRow(int rowNumber, BitArray row, Map<DecodeHintType, ?> hints)
      throws NotFoundException, ChecksumException, FormatException {

    int[] counters = new int[9];
    int[] start = findAsteriskPattern(row, counters);
    // Read off white space
    int nextStart = row.getNextSet(start[1]);
    int end = row.getSize();

    StringBuilder result = new StringBuilder(20);
    char decodedChar;
    int lastStart;
    do {
      recordPattern(row, nextStart, counters);
      int pattern = toNarrowWidePattern(counters);
      if (pattern < 0) {
        throw NotFoundException.getNotFoundInstance();
      }
      decodedChar = patternToChar(pattern);
      result.append(decodedChar);
      lastStart = nextStart;
      for (int counter : counters) {
        nextStart += counter;
      }
      // Read off white space
      nextStart = row.getNextSet(nextStart);
    } while (decodedChar != '*');
    result.setLength(result.length() - 1); // remove asterisk

    // Look for whitespace after pattern:
    int lastPatternSize = 0;
    for (int counter : counters) {
      lastPatternSize += counter;
    }
    int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;
    // If 50% of last pattern size, following last pattern, is not whitespace, fail
    // (but if it's whitespace to the very end of the image, that's OK)
    if (nextStart != end && (whiteSpaceAfterEnd >> 1) < lastPatternSize) {
      throw NotFoundException.getNotFoundInstance();
    }

    if (usingCheckDigit) {
      int max = result.length() - 1;
      int total = 0;
      for (int i = 0; i < max; i++) {
        total += ALPHABET_STRING.indexOf(result.charAt(i));
      }
      if (result.charAt(max) != ALPHABET[total % 43]) {
        throw ChecksumException.getChecksumInstance();
      }
      result.setLength(max);
    }

    if (result.length() == 0) {
      // false positive
      throw NotFoundException.getNotFoundInstance();
    }

    String resultString;
    if (extendedMode) {
      resultString = decodeExtended(result);
    } else {
      resultString = result.toString();
    }

    float left = (float) (start[1] + start[0]) / 2.0f;
    float right = (float) (nextStart + lastStart) / 2.0f;
    return new Result(
        resultString,
        null,
        new ResultPoint[] {
          new ResultPoint(left, (float) rowNumber), new ResultPoint(right, (float) rowNumber)
        },
        BarcodeFormat.CODE_39);
  }