@Override
  public Result decode(BinaryBitmap image, Map<DecodeHintType, ?> hints)
      throws NotFoundException, ChecksumException, FormatException {
    DecoderResult decoderResult;
    ResultPoint[] points;
    if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) {
      BitMatrix bits = extractPureBits(image.getBlackMatrix());
      decoderResult = decoder.decode(bits, hints);
      points = NO_POINTS;
    } else {
      DetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect(hints);
      decoderResult = decoder.decode(detectorResult.getBits(), hints);
      points = detectorResult.getPoints();
    }

    Result result =
        new Result(
            decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.QR_CODE);
    List<byte[]> byteSegments = decoderResult.getByteSegments();
    if (byteSegments != null) {
      result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
    }
    String ecLevel = decoderResult.getECLevel();
    if (ecLevel != null) {
      result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
    }
    return result;
  }
Example #2
0
  /**
   * Decodes a QR Code represented as a {@link BitMatrix}. A 1 or "true" is taken to mean a black
   * module.
   *
   * @param bits booleans representing white/black QR Code modules
   * @param hints decoding hints that should be used to influence decoding
   * @return text and bytes encoded within the QR Code
   * @throws FormatException if the QR Code cannot be decoded
   * @throws ChecksumException if error correction fails
   */
  public DecoderResult decode(BitMatrix bits, Map<DecodeHintType, ?> hints)
      throws FormatException, ChecksumException {

    // Construct a parser and read version, error-correction level
    BitMatrixParser parser = new BitMatrixParser(bits);
    FormatException fe = null;
    ChecksumException ce = null;
    try {
      return decode(parser, hints);
    } catch (FormatException e) {
      fe = e;
    } catch (ChecksumException e) {
      ce = e;
    }

    try {

      // Revert the bit matrix
      parser.remask();

      // Will be attempting a mirrored reading of the version and format info.
      parser.setMirror(true);

      // Preemptively read the version.
      parser.readVersion();

      // Preemptively read the format information.
      parser.readFormatInformation();

      /*
       * Since we're here, this means we have successfully detected some kind
       * of version and format information when mirrored. This is a good sign,
       * that the QR code may be mirrored, and we should try once more with a
       * mirrored content.
       */
      // Prepare for a mirrored reading.
      parser.mirror();

      DecoderResult result = decode(parser, hints);

      // Success! Notify the caller that the code was mirrored.
      result.setOther(new QRCodeDecoderMetaData(true));

      return result;

    } catch (FormatException | ChecksumException e) {
      // Throw the exception from the original reading
      if (fe != null) {
        throw fe;
      }
      if (ce != null) {
        throw ce;
      }
      throw e;
    }
  }
 static DecoderResult decode(int[] codewords, String ecLevel) throws FormatException {
   StringBuilder result = new StringBuilder(codewords.length * 2);
   // Get compaction mode
   int codeIndex = 1;
   int code = codewords[codeIndex++];
   PDF417ResultMetadata resultMetadata = new PDF417ResultMetadata();
   while (codeIndex < codewords[0]) {
     switch (code) {
       case TEXT_COMPACTION_MODE_LATCH:
         codeIndex = textCompaction(codewords, codeIndex, result);
         break;
       case BYTE_COMPACTION_MODE_LATCH:
         codeIndex = byteCompaction(code, codewords, codeIndex, result);
         break;
       case NUMERIC_COMPACTION_MODE_LATCH:
         codeIndex = numericCompaction(codewords, codeIndex, result);
         break;
       case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
         codeIndex = byteCompaction(code, codewords, codeIndex, result);
         break;
       case BYTE_COMPACTION_MODE_LATCH_6:
         codeIndex = byteCompaction(code, codewords, codeIndex, result);
         break;
       case BEGIN_MACRO_PDF417_CONTROL_BLOCK:
         codeIndex = decodeMacroBlock(codewords, codeIndex, resultMetadata);
         break;
       default:
         // Default to text compaction. During testing numerous barcodes
         // appeared to be missing the starting mode. In these cases defaulting
         // to text compaction seems to work.
         codeIndex--;
         codeIndex = textCompaction(codewords, codeIndex, result);
         break;
     }
     if (codeIndex < codewords.length) {
       code = codewords[codeIndex++];
     } else {
       throw FormatException.getFormatInstance();
     }
   }
   if (result.length() == 0) {
     throw FormatException.getFormatInstance();
   }
   DecoderResult decoderResult = new DecoderResult(null, result.toString(), null, ecLevel);
   decoderResult.setOther(resultMetadata);
   return decoderResult;
 }
 public Result decode(BinaryBitmap image, Hashtable hints)
     throws NotFoundException, ChecksumException, FormatException {
   DecoderResult decoderResult;
   ResultPoint[] points;
   if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) {
     BitMatrix bits = extractPureBits(image.getBlackMatrix());
     decoderResult = decoder.decode(bits);
     points = NO_POINTS;
   } else {
     DetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect();
     decoderResult = decoder.decode(detectorResult.getBits());
     points = detectorResult.getPoints();
   }
   Result result =
       new Result(
           decoderResult.getText(),
           decoderResult.getRawBytes(),
           points,
           BarcodeFormat.DATA_MATRIX);
   if (decoderResult.getByteSegments() != null) {
     result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, decoderResult.getByteSegments());
   }
   if (decoderResult.getECLevel() != null) {
     result.putMetadata(
         ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult.getECLevel().toString());
   }
   return result;
 }
  @Override
  public final Result decode(BinaryBitmap image, Map<DecodeHintType, ?> hints)
      throws NotFoundException, ChecksumException, FormatException {
    DecoderResult decoderResult;
    ResultPoint[] points;
    if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) {
      BitMatrix bits = extractPureBits(image.getBlackMatrix());
      decoderResult = decoder.decode(bits, hints);
      points = NO_POINTS;
    } else {
      DetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect(hints);
      decoderResult = decoder.decode(detectorResult.getBits(), hints);
      points = detectorResult.getPoints();
    }

    // If the code was mirrored: swap the bottom-left and the top-right
    // points.
    if (decoderResult.getOther() instanceof QRCodeDecoderMetaData) {
      ((QRCodeDecoderMetaData) decoderResult.getOther()).applyMirroredCorrection(points);
    }

    Result result =
        new Result(
            decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.QR_CODE);
    List<byte[]> byteSegments = decoderResult.getByteSegments();
    if (byteSegments != null) {
      result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
    }
    String ecLevel = decoderResult.getECLevel();
    if (ecLevel != null) {
      result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
    }
    if (decoderResult.hasStructuredAppend()) {
      result.putMetadata(
          ResultMetadataType.STRUCTURED_APPEND_SEQUENCE,
          decoderResult.getStructuredAppendSequenceNumber());
      result.putMetadata(
          ResultMetadataType.STRUCTURED_APPEND_PARITY, decoderResult.getStructuredAppendParity());
    }
    return result;
  }