Java Code Examples for com.google.zxing.common.CharacterSetECI

The following examples show how to use com.google.zxing.common.CharacterSetECI. These examples are extracted from open source projects. 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 Project: ScreenCapture   Source File: DecodedBitStreamParser.java    License: MIT License 5 votes vote down vote up
private static void decodeByteSegment(BitSource bits,
                                      StringBuilder result,
                                      int count,
                                      CharacterSetECI currentCharacterSetECI,
                                      Collection<byte[]> byteSegments,
                                      Map<DecodeHintType,?> hints) throws FormatException {
  // Don't crash trying to read more bits than we have available.
  if (8 * count > bits.available()) {
    throw FormatException.getFormatInstance();
  }

  byte[] readBytes = new byte[count];
  for (int i = 0; i < count; i++) {
    readBytes[i] = (byte) bits.readBits(8);
  }
  String encoding;
  if (currentCharacterSetECI == null) {
    // The spec isn't clear on this mode; see
    // section 6.4.5: t does not say which encoding to assuming
    // upon decoding. I have seen ISO-8859-1 used as well as
    // Shift_JIS -- without anything like an ECI designator to
    // give a hint.
    encoding = StringUtils.guessEncoding(readBytes, hints);
  } else {
    encoding = currentCharacterSetECI.name();
  }
  try {
    result.append(new String(readBytes, encoding));
  } catch (UnsupportedEncodingException ignored) {
    throw FormatException.getFormatInstance();
  }
  byteSegments.add(readBytes);
}
 
Example 2
private static void decodeByteSegment(BitSource bits,
                                      StringBuilder result,
                                      int count,
                                      CharacterSetECI currentCharacterSetECI,
                                      Collection<byte[]> byteSegments,
                                      Map<DecodeHintType,?> hints) throws FormatException {
  // Don't crash trying to read more bits than we have available.
  if (8 * count > bits.available()) {
    throw FormatException.getFormatInstance();
  }

  byte[] readBytes = new byte[count];
  for (int i = 0; i < count; i++) {
    readBytes[i] = (byte) bits.readBits(8);
  }
  String encoding;
  if (currentCharacterSetECI == null) {
    // The spec isn't clear on this mode; see
    // section 6.4.5: t does not say which encoding to assuming
    // upon decoding. I have seen ISO-8859-1 used as well as
    // Shift_JIS -- without anything like an ECI designator to
    // give a hint.
    encoding = StringUtils.guessEncoding(readBytes, hints);
  } else {
    encoding = currentCharacterSetECI.name();
  }
  try {
    result.append(new String(readBytes, encoding));
  } catch (UnsupportedEncodingException ignored) {
    throw FormatException.getFormatInstance();
  }
  byteSegments.add(readBytes);
}
 
Example 3
private static void decodeByteSegment(BitSource bits,
                                      StringBuilder result,
                                      int count,
                                      CharacterSetECI currentCharacterSetECI,
                                      Collection<byte[]> byteSegments,
                                      Map<DecodeHintType,?> hints) throws FormatException {
  // Don't crash trying to read more bits than we have available.
  if (8 * count > bits.available()) {
    throw FormatException.getFormatInstance();
  }

  byte[] readBytes = new byte[count];
  for (int i = 0; i < count; i++) {
    readBytes[i] = (byte) bits.readBits(8);
  }
  String encoding;
  if (currentCharacterSetECI == null) {
    // The spec isn't clear on this mode; see
    // section 6.4.5: t does not say which encoding to assuming
    // upon decoding. I have seen ISO-8859-1 used as well as
    // Shift_JIS -- without anything like an ECI designator to
    // give a hint.
    encoding = StringUtils.guessEncoding(readBytes, hints);
  } else {
    encoding = currentCharacterSetECI.name();
  }
  try {
    result.append(new String(readBytes, encoding));
  } catch (UnsupportedEncodingException ignored) {
    throw FormatException.getFormatInstance();
  }
  byteSegments.add(readBytes);
}
 
Example 4
Source Project: ZXing-Orient   Source File: DecodedBitStreamParser.java    License: Apache License 2.0 5 votes vote down vote up
private static void decodeByteSegment(BitSource bits,
                                      StringBuilder result,
                                      int count,
                                      CharacterSetECI currentCharacterSetECI,
                                      Collection<byte[]> byteSegments,
                                      Map<DecodeHintType,?> hints) throws FormatException {
  // Don't crash trying to read more bits than we have available.
  if (8 * count > bits.available()) {
    throw FormatException.getFormatInstance();
  }

  byte[] readBytes = new byte[count];
  for (int i = 0; i < count; i++) {
    readBytes[i] = (byte) bits.readBits(8);
  }
  String encoding;
  if (currentCharacterSetECI == null) {
    // The spec isn't clear on this mode; see
    // section 6.4.5: t does not say which encoding to assuming
    // upon decoding. I have seen ISO-8859-1 used as well as
    // Shift_JIS -- without anything like an ECI designator to
    // give a hint.
    encoding = StringUtils.guessEncoding(readBytes, hints);
  } else {
    encoding = currentCharacterSetECI.name();
  }
  try {
    result.append(new String(readBytes, encoding));
  } catch (UnsupportedEncodingException ignored) {
    throw FormatException.getFormatInstance();
  }
  byteSegments.add(readBytes);
}
 
Example 5
private static void decodeByteSegment(BitSource bits,
                                      StringBuilder result,
                                      int count,
                                      CharacterSetECI currentCharacterSetECI,
                                      Collection<byte[]> byteSegments,
                                      Map<DecodeHintType,?> hints) throws FormatException {
  // Don't crash trying to read more bits than we have available.
  if (8 * count > bits.available()) {
    throw FormatException.getFormatInstance();
  }

  byte[] readBytes = new byte[count];
  for (int i = 0; i < count; i++) {
    readBytes[i] = (byte) bits.readBits(8);
  }
  String encoding;
  if (currentCharacterSetECI == null) {
    // The spec isn't clear on this mode; see
    // section 6.4.5: t does not say which encoding to assuming
    // upon decoding. I have seen ISO-8859-1 used as well as
    // Shift_JIS -- without anything like an ECI designator to
    // give a hint.
    encoding = StringUtils.guessEncoding(readBytes, hints);
  } else {
    encoding = currentCharacterSetECI.name();
  }
  try {
    result.append(new String(readBytes, encoding));
  } catch (UnsupportedEncodingException ignored) {
    throw FormatException.getFormatInstance();
  }
  byteSegments.add(readBytes);
}
 
Example 6
Source Project: weex   Source File: DecodedBitStreamParser.java    License: Apache License 2.0 5 votes vote down vote up
private static void decodeByteSegment(BitSource bits,
                                      StringBuilder result,
                                      int count,
                                      CharacterSetECI currentCharacterSetECI,
                                      Collection<byte[]> byteSegments,
                                      Map<DecodeHintType,?> hints) throws FormatException {
  // Don't crash trying to read more bits than we have available.
  if (8 * count > bits.available()) {
    throw FormatException.getFormatInstance();
  }

  byte[] readBytes = new byte[count];
  for (int i = 0; i < count; i++) {
    readBytes[i] = (byte) bits.readBits(8);
  }
  String encoding;
  if (currentCharacterSetECI == null) {
    // The spec isn't clear on this mode; see
    // section 6.4.5: t does not say which encoding to assuming
    // upon decoding. I have seen ISO-8859-1 used as well as
    // Shift_JIS -- without anything like an ECI designator to
    // give a hint.
    encoding = StringUtils.guessEncoding(readBytes, hints);
  } else {
    encoding = currentCharacterSetECI.name();
  }
  try {
    result.append(new String(readBytes, encoding));
  } catch (UnsupportedEncodingException ignored) {
    throw FormatException.getFormatInstance();
  }
  byteSegments.add(readBytes);
}
 
Example 7
Source Project: barcodescanner-lib-aar   Source File: DecodedBitStreamParser.java    License: MIT License 5 votes vote down vote up
private static void decodeByteSegment(BitSource bits,
                                      StringBuilder result,
                                      int count,
                                      CharacterSetECI currentCharacterSetECI,
                                      Collection<byte[]> byteSegments,
                                      Map<DecodeHintType,?> hints) throws FormatException {
  // Don't crash trying to read more bits than we have available.
  if (8 * count > bits.available()) {
    throw FormatException.getFormatInstance();
  }

  byte[] readBytes = new byte[count];
  for (int i = 0; i < count; i++) {
    readBytes[i] = (byte) bits.readBits(8);
  }
  String encoding;
  if (currentCharacterSetECI == null) {
    // The spec isn't clear on this mode; see
    // section 6.4.5: t does not say which encoding to assuming
    // upon decoding. I have seen ISO-8859-1 used as well as
    // Shift_JIS -- without anything like an ECI designator to
    // give a hint.
    encoding = StringUtils.guessEncoding(readBytes, hints);
  } else {
    encoding = currentCharacterSetECI.name();
  }
  try {
    result.append(new String(readBytes, encoding));
  } catch (UnsupportedEncodingException ignored) {
    throw FormatException.getFormatInstance();
  }
  byteSegments.add(readBytes);
}
 
Example 8
Source Project: reacteu-app   Source File: DecodedBitStreamParser.java    License: MIT License 5 votes vote down vote up
private static void decodeByteSegment(BitSource bits,
                                      StringBuilder result,
                                      int count,
                                      CharacterSetECI currentCharacterSetECI,
                                      Collection<byte[]> byteSegments,
                                      Map<DecodeHintType,?> hints) throws FormatException {
  // Don't crash trying to read more bits than we have available.
  if (count << 3 > bits.available()) {
    throw FormatException.getFormatInstance();
  }

  byte[] readBytes = new byte[count];
  for (int i = 0; i < count; i++) {
    readBytes[i] = (byte) bits.readBits(8);
  }
  String encoding;
  if (currentCharacterSetECI == null) {
    // The spec isn't clear on this mode; see
    // section 6.4.5: t does not say which encoding to assuming
    // upon decoding. I have seen ISO-8859-1 used as well as
    // Shift_JIS -- without anything like an ECI designator to
    // give a hint.
    encoding = StringUtils.guessEncoding(readBytes, hints);
  } else {
    encoding = currentCharacterSetECI.name();
  }
  try {
    result.append(new String(readBytes, encoding));
  } catch (UnsupportedEncodingException uce) {
    throw FormatException.getFormatInstance();
  }
  byteSegments.add(readBytes);
}
 
Example 9
Source Project: MiBandDecompiled   Source File: m.java    License: Apache License 2.0 5 votes vote down vote up
private static void a(BitSource bitsource, StringBuilder stringbuilder, int i, CharacterSetECI characterseteci, Collection collection, Map map)
{
    if (i << 3 > bitsource.available())
    {
        throw FormatException.getFormatInstance();
    }
    byte abyte0[] = new byte[i];
    for (int j = 0; j < i; j++)
    {
        abyte0[j] = (byte)bitsource.readBits(8);
    }

    String s;
    if (characterseteci == null)
    {
        s = StringUtils.guessEncoding(abyte0, map);
    } else
    {
        s = characterseteci.name();
    }
    try
    {
        stringbuilder.append(new String(abyte0, s));
    }
    catch (UnsupportedEncodingException unsupportedencodingexception)
    {
        throw FormatException.getFormatInstance();
    }
    collection.add(abyte0);
}
 
Example 10
Source Project: RipplePower   Source File: DecodedBitStreamParser.java    License: Apache License 2.0 5 votes vote down vote up
private static void decodeByteSegment(BitSource bits, StringBuilder result, int count,
		CharacterSetECI currentCharacterSetECI, Collection<byte[]> byteSegments, Map<DecodeHintType, ?> hints)
		throws FormatException {
	// Don't crash trying to read more bits than we have available.
	if (8 * count > bits.available()) {
		throw FormatException.getFormatInstance();
	}

	byte[] readBytes = new byte[count];
	for (int i = 0; i < count; i++) {
		readBytes[i] = (byte) bits.readBits(8);
	}
	String encoding;
	if (currentCharacterSetECI == null) {
		// The spec isn't clear on this mode; see
		// section 6.4.5: t does not say which encoding to assuming
		// upon decoding. I have seen ISO-8859-1 used as well as
		// Shift_JIS -- without anything like an ECI designator to
		// give a hint.
		encoding = StringUtils.guessEncoding(readBytes, hints);
	} else {
		encoding = currentCharacterSetECI.name();
	}
	try {
		result.append(new String(readBytes, encoding));
	} catch (UnsupportedEncodingException ignored) {
		throw FormatException.getFormatInstance();
	}
	byteSegments.add(readBytes);
}
 
Example 11
private static void decodeByteSegment(BitSource bits,
                                      StringBuilder result,
                                      int count,
                                      CharacterSetECI currentCharacterSetECI,
                                      Collection<byte[]> byteSegments,
                                      Map<DecodeHintType,?> hints) throws FormatException {
  // Don't crash trying to read more bits than we have available.
  if (8 * count > bits.available()) {
    throw FormatException.getFormatInstance();
  }

  byte[] readBytes = new byte[count];
  for (int i = 0; i < count; i++) {
    readBytes[i] = (byte) bits.readBits(8);
  }
  String encoding;
  if (currentCharacterSetECI == null) {
    // The spec isn't clear on this mode; see
    // section 6.4.5: t does not say which encoding to assuming
    // upon decoding. I have seen ISO-8859-1 used as well as
    // Shift_JIS -- without anything like an ECI designator to
    // give a hint.
    encoding = StringUtils.guessEncoding(readBytes, hints);
  } else {
    encoding = currentCharacterSetECI.name();
  }
  try {
    result.append(new String(readBytes, encoding));
  } catch (UnsupportedEncodingException ignored) {
    throw FormatException.getFormatInstance();
  }
  byteSegments.add(readBytes);
}
 
Example 12
Source Project: barterli_android   Source File: DecodedBitStreamParser.java    License: Apache License 2.0 5 votes vote down vote up
private static void decodeByteSegment(BitSource bits, StringBuilder result, int count, CharacterSetECI currentCharacterSetECI,
        Collection<byte[]> byteSegments, Map<DecodeHintType, ?> hints) throws FormatException {
    // Don't crash trying to read more bits than we have available.
    if (count << 3 > bits.available()) {
        throw FormatException.getFormatInstance();
    }

    byte[] readBytes = new byte[count];
    for (int i = 0; i < count; i++) {
        readBytes[i] = (byte) bits.readBits(8);
    }
    String encoding;
    if (currentCharacterSetECI == null) {
        // The spec isn't clear on this mode; see
        // section 6.4.5: t does not say which encoding to assuming
        // upon decoding. I have seen ISO-8859-1 used as well as
        // Shift_JIS -- without anything like an ECI designator to
        // give a hint.
        encoding = StringUtils.guessEncoding(readBytes, hints);
    } else {
        encoding = currentCharacterSetECI.name();
    }
    try {
        result.append(new String(readBytes, encoding));
    } catch (UnsupportedEncodingException uce) {
        throw FormatException.getFormatInstance();
    }
    byteSegments.add(readBytes);
}
 
Example 13
private static void decodeByteSegment(BitSource bits, StringBuilder result, int count, CharacterSetECI currentCharacterSetECI,
        Collection<byte[]> byteSegments, Map<DecodeHintType, ?> hints) throws FormatException {
    // Don't crash trying to read more bits than we have available.
    if (count << 3 > bits.available()) {
        throw FormatException.getFormatInstance();
    }

    byte[] readBytes = new byte[count];
    for (int i = 0; i < count; i++) {
        readBytes[i] = (byte) bits.readBits(8);
    }
    String encoding;
    if (currentCharacterSetECI == null) {
        // The spec isn't clear on this mode; see
        // section 6.4.5: t does not say which encoding to assuming
        // upon decoding. I have seen ISO-8859-1 used as well as
        // Shift_JIS -- without anything like an ECI designator to
        // give a hint.
        encoding = StringUtils.guessEncoding(readBytes, hints);
    } else {
        encoding = currentCharacterSetECI.name();
    }
    try {
        result.append(new String(readBytes, encoding));
    } catch (UnsupportedEncodingException uce) {
        throw FormatException.getFormatInstance();
    }
    byteSegments.add(readBytes);
}
 
Example 14
private static void decodeByteSegment(BitSource bits,
                                      StringBuilder result,
                                      int count,
                                      CharacterSetECI currentCharacterSetECI,
                                      Collection<byte[]> byteSegments,
                                      Map<DecodeHintType,?> hints) throws FormatException {
  // Don't crash trying to read more bits than we have available.
  if (8 * count > bits.available()) {
    throw FormatException.getFormatInstance();
  }

  byte[] readBytes = new byte[count];
  for (int i = 0; i < count; i++) {
    readBytes[i] = (byte) bits.readBits(8);
  }
  String encoding;
  if (currentCharacterSetECI == null) {
    // The spec isn't clear on this mode; see
    // section 6.4.5: t does not say which encoding to assuming
    // upon decoding. I have seen ISO-8859-1 used as well as
    // Shift_JIS -- without anything like an ECI designator to
    // give a hint.
    encoding = StringUtils.guessEncoding(readBytes, hints);
  } else {
    encoding = currentCharacterSetECI.name();
  }
  try {
    result.append(new String(readBytes, encoding));
  } catch (UnsupportedEncodingException ignored) {
    throw FormatException.getFormatInstance();
  }
  byteSegments.add(readBytes);
}
 
Example 15
Source Project: ScreenCapture   Source File: Encoder.java    License: MIT License 4 votes vote down vote up
public static QRCode encode(String content,
                            ErrorCorrectionLevel ecLevel,
                            Map<EncodeHintType,?> hints) throws WriterException {

  // Determine what character encoding has been specified by the caller, if any
  String encoding = DEFAULT_BYTE_MODE_ENCODING;
  boolean hasEncodingHint = hints != null && hints.containsKey(EncodeHintType.CHARACTER_SET);
  if (hasEncodingHint) {
    encoding = hints.get(EncodeHintType.CHARACTER_SET).toString();
  }

  // Pick an encoding mode appropriate for the content. Note that this will not attempt to use
  // multiple modes / segments even if that were more efficient. Twould be nice.
  Mode mode = chooseMode(content, encoding);

  // This will store the header information, like mode and
  // length, as well as "header" segments like an ECI segment.
  BitArray headerBits = new BitArray();

  // Append ECI segment if applicable
  if (mode == Mode.BYTE && (hasEncodingHint || !DEFAULT_BYTE_MODE_ENCODING.equals(encoding))) {
    CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding);
    if (eci != null) {
      appendECI(eci, headerBits);
    }
  }

  // (With ECI in place,) Write the mode marker
  appendModeInfo(mode, headerBits);

  // Collect data within the main segment, separately, to count its size if needed. Don't add it to
  // main payload yet.
  BitArray dataBits = new BitArray();
  appendBytes(content, mode, dataBits, encoding);

  Version version;
  if (hints != null && hints.containsKey(EncodeHintType.QR_VERSION)) {
    int versionNumber = Integer.parseInt(hints.get(EncodeHintType.QR_VERSION).toString());
    version = Version.getVersionForNumber(versionNumber);
    int bitsNeeded = calculateBitsNeeded(mode, headerBits, dataBits, version);
    if (!willFit(bitsNeeded, version, ecLevel)) {
      throw new WriterException("Data too big for requested version");
    }
  } else {
    version = recommendVersion(ecLevel, mode, headerBits, dataBits);
  }

  BitArray headerAndDataBits = new BitArray();
  headerAndDataBits.appendBitArray(headerBits);
  // Find "length" of main segment and write it
  int numLetters = mode == Mode.BYTE ? dataBits.getSizeInBytes() : content.length();
  appendLengthInfo(numLetters, version, mode, headerAndDataBits);
  // Put data together into the overall payload
  headerAndDataBits.appendBitArray(dataBits);

  Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);
  int numDataBytes = version.getTotalCodewords() - ecBlocks.getTotalECCodewords();

  // Terminate the bits properly.
  terminateBits(numDataBytes, headerAndDataBits);

  // Interleave data bits with error correction code.
  BitArray finalBits = interleaveWithECBytes(headerAndDataBits,
                                             version.getTotalCodewords(),
                                             numDataBytes,
                                             ecBlocks.getNumBlocks());

  QRCode qrCode = new QRCode();

  qrCode.setECLevel(ecLevel);
  qrCode.setMode(mode);
  qrCode.setVersion(version);

  //  Choose the mask pattern and set to "qrCode".
  int dimension = version.getDimensionForVersion();
  ByteMatrix matrix = new ByteMatrix(dimension, dimension);
  int maskPattern = chooseMaskPattern(finalBits, ecLevel, version, matrix);
  qrCode.setMaskPattern(maskPattern);

  // Build the matrix and set it to "qrCode".
  MatrixUtil.buildMatrix(finalBits, ecLevel, version, maskPattern, matrix);
  qrCode.setMatrix(matrix);

  return qrCode;
}
 
Example 16
Source Project: ScreenCapture   Source File: Encoder.java    License: MIT License 4 votes vote down vote up
private static void appendECI(CharacterSetECI eci, BitArray bits) {
  bits.appendBits(Mode.ECI.getBits(), 4);
  // This is correct for values up to 127, which is all we need now.
  bits.appendBits(eci.getValue(), 8);
}
 
Example 17
Source Project: ScreenCapture   Source File: DecodedBitStreamParser.java    License: MIT License 4 votes vote down vote up
static DecoderResult decode(byte[] bytes,
                            Version version,
                            ErrorCorrectionLevel ecLevel,
                            Map<DecodeHintType,?> hints) throws FormatException {
  BitSource bits = new BitSource(bytes);
  StringBuilder result = new StringBuilder(50);
  List<byte[]> byteSegments = new ArrayList<>(1);
  int symbolSequence = -1;
  int parityData = -1;

  try {
    CharacterSetECI currentCharacterSetECI = null;
    boolean fc1InEffect = false;
    Mode mode;
    do {
      // While still another segment to read...
      if (bits.available() < 4) {
        // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here
        mode = Mode.TERMINATOR;
      } else {
        mode = Mode.forBits(bits.readBits(4)); // mode is encoded by 4 bits
      }
      switch (mode) {
        case TERMINATOR:
          break;
        case FNC1_FIRST_POSITION:
        case FNC1_SECOND_POSITION:
          // We do little with FNC1 except alter the parsed result a bit according to the spec
          fc1InEffect = true;
          break;
        case STRUCTURED_APPEND:
          if (bits.available() < 16) {
            throw FormatException.getFormatInstance();
          }
          // sequence number and parity is added later to the result metadata
          // Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue
          symbolSequence = bits.readBits(8);
          parityData = bits.readBits(8);
          break;
        case ECI:
          // Count doesn't apply to ECI
          int value = parseECIValue(bits);
          currentCharacterSetECI = CharacterSetECI.getCharacterSetECIByValue(value);
          if (currentCharacterSetECI == null) {
            throw FormatException.getFormatInstance();
          }
          break;
        case HANZI:
          // First handle Hanzi mode which does not start with character count
          // Chinese mode contains a sub set indicator right after mode indicator
          int subset = bits.readBits(4);
          int countHanzi = bits.readBits(mode.getCharacterCountBits(version));
          if (subset == GB2312_SUBSET) {
            decodeHanziSegment(bits, result, countHanzi);
          }
          break;
        default:
          // "Normal" QR code modes:
          // How many characters will follow, encoded in this mode?
          int count = bits.readBits(mode.getCharacterCountBits(version));
          switch (mode) {
            case NUMERIC:
              decodeNumericSegment(bits, result, count);
              break;
            case ALPHANUMERIC:
              decodeAlphanumericSegment(bits, result, count, fc1InEffect);
              break;
            case BYTE:
              decodeByteSegment(bits, result, count, currentCharacterSetECI, byteSegments, hints);
              break;
            case KANJI:
              decodeKanjiSegment(bits, result, count);
              break;
            default:
              throw FormatException.getFormatInstance();
          }
          break;
      }
    } while (mode != Mode.TERMINATOR);
  } catch (IllegalArgumentException iae) {
    // from readBits() calls
    throw FormatException.getFormatInstance();
  }

  return new DecoderResult(bytes,
                           result.toString(),
                           byteSegments.isEmpty() ? null : byteSegments,
                           ecLevel == null ? null : ecLevel.toString(),
                           symbolSequence,
                           parityData);
}
 
Example 18
Source Project: Tesseract-OCR-Scanner   Source File: Encoder.java    License: Apache License 2.0 4 votes vote down vote up
public static QRCode encode(String content,
                            ErrorCorrectionLevel ecLevel,
                            Map<EncodeHintType,?> hints) throws WriterException {

  // Determine what character encoding has been specified by the caller, if any
  String encoding = DEFAULT_BYTE_MODE_ENCODING;
  boolean hasEncodingHint = hints != null && hints.containsKey(EncodeHintType.CHARACTER_SET);
  if (hasEncodingHint) {
    encoding = hints.get(EncodeHintType.CHARACTER_SET).toString();
  }

  // Pick an encoding mode appropriate for the content. Note that this will not attempt to use
  // multiple modes / segments even if that were more efficient. Twould be nice.
  Mode mode = chooseMode(content, encoding);

  // This will store the header information, like mode and
  // length, as well as "header" segments like an ECI segment.
  BitArray headerBits = new BitArray();

  // Append ECI segment if applicable
  if (mode == Mode.BYTE && (hasEncodingHint || !DEFAULT_BYTE_MODE_ENCODING.equals(encoding))) {
    CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding);
    if (eci != null) {
      appendECI(eci, headerBits);
    }
  }

  // (With ECI in place,) Write the mode marker
  appendModeInfo(mode, headerBits);

  // Collect data within the main segment, separately, to count its size if needed. Don't add it to
  // main payload yet.
  BitArray dataBits = new BitArray();
  appendBytes(content, mode, dataBits, encoding);

  Version version;
  if (hints != null && hints.containsKey(EncodeHintType.QR_VERSION)) {
    int versionNumber = Integer.parseInt(hints.get(EncodeHintType.QR_VERSION).toString());
    version = Version.getVersionForNumber(versionNumber);
    int bitsNeeded = calculateBitsNeeded(mode, headerBits, dataBits, version);
    if (!willFit(bitsNeeded, version, ecLevel)) {
      throw new WriterException("Data too big for requested version");
    }
  } else {
    version = recommendVersion(ecLevel, mode, headerBits, dataBits);
  }

  BitArray headerAndDataBits = new BitArray();
  headerAndDataBits.appendBitArray(headerBits);
  // Find "length" of main segment and write it
  int numLetters = mode == Mode.BYTE ? dataBits.getSizeInBytes() : content.length();
  appendLengthInfo(numLetters, version, mode, headerAndDataBits);
  // Put data together into the overall payload
  headerAndDataBits.appendBitArray(dataBits);

  Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);
  int numDataBytes = version.getTotalCodewords() - ecBlocks.getTotalECCodewords();

  // Terminate the bits properly.
  terminateBits(numDataBytes, headerAndDataBits);

  // Interleave data bits with error correction code.
  BitArray finalBits = interleaveWithECBytes(headerAndDataBits,
                                             version.getTotalCodewords(),
                                             numDataBytes,
                                             ecBlocks.getNumBlocks());

  QRCode qrCode = new QRCode();

  qrCode.setECLevel(ecLevel);
  qrCode.setMode(mode);
  qrCode.setVersion(version);

  //  Choose the mask pattern and set to "qrCode".
  int dimension = version.getDimensionForVersion();
  ByteMatrix matrix = new ByteMatrix(dimension, dimension);
  int maskPattern = chooseMaskPattern(finalBits, ecLevel, version, matrix);
  qrCode.setMaskPattern(maskPattern);

  // Build the matrix and set it to "qrCode".
  MatrixUtil.buildMatrix(finalBits, ecLevel, version, maskPattern, matrix);
  qrCode.setMatrix(matrix);

  return qrCode;
}
 
Example 19
Source Project: Tesseract-OCR-Scanner   Source File: Encoder.java    License: Apache License 2.0 4 votes vote down vote up
private static void appendECI(CharacterSetECI eci, BitArray bits) {
  bits.appendBits(Mode.ECI.getBits(), 4);
  // This is correct for values up to 127, which is all we need now.
  bits.appendBits(eci.getValue(), 8);
}
 
Example 20
static DecoderResult decode(byte[] bytes,
                            Version version,
                            ErrorCorrectionLevel ecLevel,
                            Map<DecodeHintType,?> hints) throws FormatException {
  BitSource bits = new BitSource(bytes);
  StringBuilder result = new StringBuilder(50);
  List<byte[]> byteSegments = new ArrayList<>(1);
  int symbolSequence = -1;
  int parityData = -1;

  try {
    CharacterSetECI currentCharacterSetECI = null;
    boolean fc1InEffect = false;
    Mode mode;
    do {
      // While still another segment to read...
      if (bits.available() < 4) {
        // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here
        mode = Mode.TERMINATOR;
      } else {
        mode = Mode.forBits(bits.readBits(4)); // mode is encoded by 4 bits
      }
      switch (mode) {
        case TERMINATOR:
          break;
        case FNC1_FIRST_POSITION:
        case FNC1_SECOND_POSITION:
          // We do little with FNC1 except alter the parsed result a bit according to the spec
          fc1InEffect = true;
          break;
        case STRUCTURED_APPEND:
          if (bits.available() < 16) {
            throw FormatException.getFormatInstance();
          }
          // sequence number and parity is added later to the result metadata
          // Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue
          symbolSequence = bits.readBits(8);
          parityData = bits.readBits(8);
          break;
        case ECI:
          // Count doesn't apply to ECI
          int value = parseECIValue(bits);
          currentCharacterSetECI = CharacterSetECI.getCharacterSetECIByValue(value);
          if (currentCharacterSetECI == null) {
            throw FormatException.getFormatInstance();
          }
          break;
        case HANZI:
          // First handle Hanzi mode which does not start with character count
          // Chinese mode contains a sub set indicator right after mode indicator
          int subset = bits.readBits(4);
          int countHanzi = bits.readBits(mode.getCharacterCountBits(version));
          if (subset == GB2312_SUBSET) {
            decodeHanziSegment(bits, result, countHanzi);
          }
          break;
        default:
          // "Normal" QR code modes:
          // How many characters will follow, encoded in this mode?
          int count = bits.readBits(mode.getCharacterCountBits(version));
          switch (mode) {
            case NUMERIC:
              decodeNumericSegment(bits, result, count);
              break;
            case ALPHANUMERIC:
              decodeAlphanumericSegment(bits, result, count, fc1InEffect);
              break;
            case BYTE:
              decodeByteSegment(bits, result, count, currentCharacterSetECI, byteSegments, hints);
              break;
            case KANJI:
              decodeKanjiSegment(bits, result, count);
              break;
            default:
              throw FormatException.getFormatInstance();
          }
          break;
      }
    } while (mode != Mode.TERMINATOR);
  } catch (IllegalArgumentException iae) {
    // from readBits() calls
    throw FormatException.getFormatInstance();
  }

  return new DecoderResult(bytes,
                           result.toString(),
                           byteSegments.isEmpty() ? null : byteSegments,
                           ecLevel == null ? null : ecLevel.toString(),
                           symbolSequence,
                           parityData);
}
 
Example 21
Source Project: QrCodeScanner   Source File: Encoder.java    License: GNU General Public License v3.0 4 votes vote down vote up
public static QRCode encode(String content,
                            ErrorCorrectionLevel ecLevel,
                            Map<EncodeHintType,?> hints) throws WriterException {

  // Determine what character encoding has been specified by the caller, if any
  String encoding = DEFAULT_BYTE_MODE_ENCODING;
  boolean hasEncodingHint = hints != null && hints.containsKey(EncodeHintType.CHARACTER_SET);
  if (hasEncodingHint) {
    encoding = hints.get(EncodeHintType.CHARACTER_SET).toString();
  }

  // Pick an encoding mode appropriate for the content. Note that this will not attempt to use
  // multiple modes / segments even if that were more efficient. Twould be nice.
  Mode mode = chooseMode(content, encoding);

  // This will store the header information, like mode and
  // length, as well as "header" segments like an ECI segment.
  BitArray headerBits = new BitArray();

  // Append ECI segment if applicable
  if (mode == Mode.BYTE && (hasEncodingHint || !DEFAULT_BYTE_MODE_ENCODING.equals(encoding))) {
    CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding);
    if (eci != null) {
      appendECI(eci, headerBits);
    }
  }

  // (With ECI in place,) Write the mode marker
  appendModeInfo(mode, headerBits);

  // Collect data within the main segment, separately, to count its size if needed. Don't add it to
  // main payload yet.
  BitArray dataBits = new BitArray();
  appendBytes(content, mode, dataBits, encoding);

  Version version;
  if (hints != null && hints.containsKey(EncodeHintType.QR_VERSION)) {
    int versionNumber = Integer.parseInt(hints.get(EncodeHintType.QR_VERSION).toString());
    version = Version.getVersionForNumber(versionNumber);
    int bitsNeeded = calculateBitsNeeded(mode, headerBits, dataBits, version);
    if (!willFit(bitsNeeded, version, ecLevel)) {
      throw new WriterException("Data too big for requested version");
    }
  } else {
    version = recommendVersion(ecLevel, mode, headerBits, dataBits);
  }

  BitArray headerAndDataBits = new BitArray();
  headerAndDataBits.appendBitArray(headerBits);
  // Find "length" of main segment and write it
  int numLetters = mode == Mode.BYTE ? dataBits.getSizeInBytes() : content.length();
  appendLengthInfo(numLetters, version, mode, headerAndDataBits);
  // Put data together into the overall payload
  headerAndDataBits.appendBitArray(dataBits);

  Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);
  int numDataBytes = version.getTotalCodewords() - ecBlocks.getTotalECCodewords();

  // Terminate the bits properly.
  terminateBits(numDataBytes, headerAndDataBits);

  // Interleave data bits with error correction code.
  BitArray finalBits = interleaveWithECBytes(headerAndDataBits,
                                             version.getTotalCodewords(),
                                             numDataBytes,
                                             ecBlocks.getNumBlocks());

  QRCode qrCode = new QRCode();

  qrCode.setECLevel(ecLevel);
  qrCode.setMode(mode);
  qrCode.setVersion(version);

  //  Choose the mask pattern and set to "qrCode".
  int dimension = version.getDimensionForVersion();
  ByteMatrix matrix = new ByteMatrix(dimension, dimension);
  int maskPattern = chooseMaskPattern(finalBits, ecLevel, version, matrix);
  qrCode.setMaskPattern(maskPattern);

  // Build the matrix and set it to "qrCode".
  MatrixUtil.buildMatrix(finalBits, ecLevel, version, maskPattern, matrix);
  qrCode.setMatrix(matrix);

  return qrCode;
}
 
Example 22
Source Project: QrCodeScanner   Source File: Encoder.java    License: GNU General Public License v3.0 4 votes vote down vote up
private static void appendECI(CharacterSetECI eci, BitArray bits) {
  bits.appendBits(Mode.ECI.getBits(), 4);
  // This is correct for values up to 127, which is all we need now.
  bits.appendBits(eci.getValue(), 8);
}
 
Example 23
static DecoderResult decode(byte[] bytes,
                            Version version,
                            ErrorCorrectionLevel ecLevel,
                            Map<DecodeHintType,?> hints) throws FormatException {
  BitSource bits = new BitSource(bytes);
  StringBuilder result = new StringBuilder(50);
  List<byte[]> byteSegments = new ArrayList<>(1);
  int symbolSequence = -1;
  int parityData = -1;

  try {
    CharacterSetECI currentCharacterSetECI = null;
    boolean fc1InEffect = false;
    Mode mode;
    do {
      // While still another segment to read...
      if (bits.available() < 4) {
        // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here
        mode = Mode.TERMINATOR;
      } else {
        mode = Mode.forBits(bits.readBits(4)); // mode is encoded by 4 bits
      }
      switch (mode) {
        case TERMINATOR:
          break;
        case FNC1_FIRST_POSITION:
        case FNC1_SECOND_POSITION:
          // We do little with FNC1 except alter the parsed result a bit according to the spec
          fc1InEffect = true;
          break;
        case STRUCTURED_APPEND:
          if (bits.available() < 16) {
            throw FormatException.getFormatInstance();
          }
          // sequence number and parity is added later to the result metadata
          // Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue
          symbolSequence = bits.readBits(8);
          parityData = bits.readBits(8);
          break;
        case ECI:
          // Count doesn't apply to ECI
          int value = parseECIValue(bits);
          currentCharacterSetECI = CharacterSetECI.getCharacterSetECIByValue(value);
          if (currentCharacterSetECI == null) {
            throw FormatException.getFormatInstance();
          }
          break;
        case HANZI:
          // First handle Hanzi mode which does not start with character count
          // Chinese mode contains a sub set indicator right after mode indicator
          int subset = bits.readBits(4);
          int countHanzi = bits.readBits(mode.getCharacterCountBits(version));
          if (subset == GB2312_SUBSET) {
            decodeHanziSegment(bits, result, countHanzi);
          }
          break;
        default:
          // "Normal" QR code modes:
          // How many characters will follow, encoded in this mode?
          int count = bits.readBits(mode.getCharacterCountBits(version));
          switch (mode) {
            case NUMERIC:
              decodeNumericSegment(bits, result, count);
              break;
            case ALPHANUMERIC:
              decodeAlphanumericSegment(bits, result, count, fc1InEffect);
              break;
            case BYTE:
              decodeByteSegment(bits, result, count, currentCharacterSetECI, byteSegments, hints);
              break;
            case KANJI:
              decodeKanjiSegment(bits, result, count);
              break;
            default:
              throw FormatException.getFormatInstance();
          }
          break;
      }
    } while (mode != Mode.TERMINATOR);
  } catch (IllegalArgumentException iae) {
    // from readBits() calls
    throw FormatException.getFormatInstance();
  }

  return new DecoderResult(bytes,
                           result.toString(),
                           byteSegments.isEmpty() ? null : byteSegments,
                           ecLevel == null ? null : ecLevel.toString(),
                           symbolSequence,
                           parityData);
}
 
Example 24
Source Project: ZXing-Orient   Source File: PDF417HighLevelEncoder.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * Performs high-level encoding of a PDF417 message using the algorithm described in annex P
 * of ISO/IEC 15438:2001(E). If byte compaction has been selected, then only byte compaction
 * is used.
 *
 * @param msg the message
 * @param compaction compaction mode to use
 * @param encoding character encoding used to encode in default or byte compaction
 *  or {@code null} for default / not applicable
 * @return the encoded message (the char values range from 0 to 928)
 */
static String encodeHighLevel(String msg, Compaction compaction, Charset encoding) throws WriterException {

  //the codewords 0..928 are encoded as Unicode characters
  StringBuilder sb = new StringBuilder(msg.length());

  if (encoding != null && !DEFAULT_ENCODING_NAMES.contains(encoding.name())) {
    CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding.name());
    if (eci != null) {
      encodingECI(eci.getValue(), sb);
    }
  }

  int len = msg.length();
  int p = 0;
  int textSubMode = SUBMODE_ALPHA;

  // User selected encoding mode
  byte[] bytes = null; //Fill later and only if needed
  if (compaction == Compaction.TEXT) {
    encodeText(msg, p, len, sb, textSubMode);

  } else if (compaction == Compaction.BYTE) {
    bytes = toBytes(msg, encoding);
    encodeBinary(bytes, p, bytes.length, BYTE_COMPACTION, sb);

  } else if (compaction == Compaction.NUMERIC) {
    sb.append((char) LATCH_TO_NUMERIC);
    encodeNumeric(msg, p, len, sb);

  } else {
    int encodingMode = TEXT_COMPACTION; //Default mode, see 4.4.2.1
    while (p < len) {
      int n = determineConsecutiveDigitCount(msg, p);
      if (n >= 13) {
        sb.append((char) LATCH_TO_NUMERIC);
        encodingMode = NUMERIC_COMPACTION;
        textSubMode = SUBMODE_ALPHA; //Reset after latch
        encodeNumeric(msg, p, n, sb);
        p += n;
      } else {
        int t = determineConsecutiveTextCount(msg, p);
        if (t >= 5 || n == len) {
          if (encodingMode != TEXT_COMPACTION) {
            sb.append((char) LATCH_TO_TEXT);
            encodingMode = TEXT_COMPACTION;
            textSubMode = SUBMODE_ALPHA; //start with submode alpha after latch
          }
          textSubMode = encodeText(msg, p, t, sb, textSubMode);
          p += t;
        } else {
          if (bytes == null) {
            bytes = toBytes(msg, encoding);
          }
          int b = determineConsecutiveBinaryCount(msg, bytes, p);
          if (b == 0) {
            b = 1;
          }
          if (b == 1 && encodingMode == TEXT_COMPACTION) {
            //Switch for one byte (instead of latch)
            encodeBinary(bytes, p, 1, TEXT_COMPACTION, sb);
          } else {
            //Mode latch performed by encodeBinary()
            encodeBinary(bytes, p, b, encodingMode, sb);
            encodingMode = BYTE_COMPACTION;
            textSubMode = SUBMODE_ALPHA; //Reset after latch
          }
          p += b;
        }
      }
    }
  }

  return sb.toString();
}
 
Example 25
Source Project: ZXing-Orient   Source File: Encoder.java    License: Apache License 2.0 4 votes vote down vote up
public static QRCode encode(String content,
                            ErrorCorrectionLevel ecLevel,
                            Map<EncodeHintType,?> hints) throws WriterException {

  // Determine what character encoding has been specified by the caller, if any
  String encoding = hints == null ? null : (String) hints.get(EncodeHintType.CHARACTER_SET);
  if (encoding == null) {
    encoding = DEFAULT_BYTE_MODE_ENCODING;
  }

  // Pick an encoding mode appropriate for the content. Note that this will not attempt to use
  // multiple modes / segments even if that were more efficient. Twould be nice.
  Mode mode = chooseMode(content, encoding);

  // This will store the header information, like mode and
  // length, as well as "header" segments like an ECI segment.
  BitArray headerBits = new BitArray();

  // Append ECI segment if applicable
  if (mode == Mode.BYTE && !DEFAULT_BYTE_MODE_ENCODING.equals(encoding)) {
    CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding);
    if (eci != null) {
      appendECI(eci, headerBits);
    }
  }

  // (With ECI in place,) Write the mode marker
  appendModeInfo(mode, headerBits);

  // Collect data within the main segment, separately, to count its size if needed. Don't add it to
  // main payload yet.
  BitArray dataBits = new BitArray();
  appendBytes(content, mode, dataBits, encoding);

  // Hard part: need to know version to know how many bits length takes. But need to know how many
  // bits it takes to know version. First we take a guess at version by assuming version will be
  // the minimum, 1:

  int provisionalBitsNeeded = headerBits.getSize()
      + mode.getCharacterCountBits(Version.getVersionForNumber(1))
      + dataBits.getSize();
  Version provisionalVersion = chooseVersion(provisionalBitsNeeded, ecLevel);

  // Use that guess to calculate the right version. I am still not sure this works in 100% of cases.

  int bitsNeeded = headerBits.getSize()
      + mode.getCharacterCountBits(provisionalVersion)
      + dataBits.getSize();
  Version version = chooseVersion(bitsNeeded, ecLevel);

  BitArray headerAndDataBits = new BitArray();
  headerAndDataBits.appendBitArray(headerBits);
  // Find "length" of main segment and write it
  int numLetters = mode == Mode.BYTE ? dataBits.getSizeInBytes() : content.length();
  appendLengthInfo(numLetters, version, mode, headerAndDataBits);
  // Put data together into the overall payload
  headerAndDataBits.appendBitArray(dataBits);

  Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);
  int numDataBytes = version.getTotalCodewords() - ecBlocks.getTotalECCodewords();

  // Terminate the bits properly.
  terminateBits(numDataBytes, headerAndDataBits);

  // Interleave data bits with error correction code.
  BitArray finalBits = interleaveWithECBytes(headerAndDataBits,
                                             version.getTotalCodewords(),
                                             numDataBytes,
                                             ecBlocks.getNumBlocks());

  QRCode qrCode = new QRCode();

  qrCode.setECLevel(ecLevel);
  qrCode.setMode(mode);
  qrCode.setVersion(version);

  //  Choose the mask pattern and set to "qrCode".
  int dimension = version.getDimensionForVersion();
  ByteMatrix matrix = new ByteMatrix(dimension, dimension);
  int maskPattern = chooseMaskPattern(finalBits, ecLevel, version, matrix);
  qrCode.setMaskPattern(maskPattern);

  // Build the matrix and set it to "qrCode".
  MatrixUtil.buildMatrix(finalBits, ecLevel, version, maskPattern, matrix);
  qrCode.setMatrix(matrix);

  return qrCode;
}
 
Example 26
Source Project: ZXing-Orient   Source File: Encoder.java    License: Apache License 2.0 4 votes vote down vote up
private static void appendECI(CharacterSetECI eci, BitArray bits) {
  bits.appendBits(Mode.ECI.getBits(), 4);
  // This is correct for values up to 127, which is all we need now.
  bits.appendBits(eci.getValue(), 8);
}
 
Example 27
Source Project: ZXing-Orient   Source File: DecodedBitStreamParser.java    License: Apache License 2.0 4 votes vote down vote up
static DecoderResult decode(byte[] bytes,
                            Version version,
                            ErrorCorrectionLevel ecLevel,
                            Map<DecodeHintType,?> hints) throws FormatException {
  BitSource bits = new BitSource(bytes);
  StringBuilder result = new StringBuilder(50);
  List<byte[]> byteSegments = new ArrayList<>(1);
  int symbolSequence = -1;
  int parityData = -1;
  
  try {
    CharacterSetECI currentCharacterSetECI = null;
    boolean fc1InEffect = false;
    Mode mode;
    do {
      // While still another segment to read...
      if (bits.available() < 4) {
        // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here
        mode = Mode.TERMINATOR;
      } else {
        mode = Mode.forBits(bits.readBits(4)); // mode is encoded by 4 bits
      }
      if (mode != Mode.TERMINATOR) {
        if (mode == Mode.FNC1_FIRST_POSITION || mode == Mode.FNC1_SECOND_POSITION) {
          // We do little with FNC1 except alter the parsed result a bit according to the spec
          fc1InEffect = true;
        } else if (mode == Mode.STRUCTURED_APPEND) {
          if (bits.available() < 16) {
            throw FormatException.getFormatInstance();
          }
          // sequence number and parity is added later to the result metadata
          // Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue
          symbolSequence = bits.readBits(8);
          parityData = bits.readBits(8);
        } else if (mode == Mode.ECI) {
          // Count doesn't apply to ECI
          int value = parseECIValue(bits);
          currentCharacterSetECI = CharacterSetECI.getCharacterSetECIByValue(value);
          if (currentCharacterSetECI == null) {
            throw FormatException.getFormatInstance();
          }
        } else {
          // First handle Hanzi mode which does not start with character count
          if (mode == Mode.HANZI) {
            //chinese mode contains a sub set indicator right after mode indicator
            int subset = bits.readBits(4);
            int countHanzi = bits.readBits(mode.getCharacterCountBits(version));
            if (subset == GB2312_SUBSET) {
              decodeHanziSegment(bits, result, countHanzi);
            }
          } else {
            // "Normal" QR code modes:
            // How many characters will follow, encoded in this mode?
            int count = bits.readBits(mode.getCharacterCountBits(version));
            if (mode == Mode.NUMERIC) {
              decodeNumericSegment(bits, result, count);
            } else if (mode == Mode.ALPHANUMERIC) {
              decodeAlphanumericSegment(bits, result, count, fc1InEffect);
            } else if (mode == Mode.BYTE) {
              decodeByteSegment(bits, result, count, currentCharacterSetECI, byteSegments, hints);
            } else if (mode == Mode.KANJI) {
              decodeKanjiSegment(bits, result, count);
            } else {
              throw FormatException.getFormatInstance();
            }
          }
        }
      }
    } while (mode != Mode.TERMINATOR);
  } catch (IllegalArgumentException iae) {
    // from readBits() calls
    throw FormatException.getFormatInstance();
  }

  return new DecoderResult(bytes,
                           result.toString(),
                           byteSegments.isEmpty() ? null : byteSegments,
                           ecLevel == null ? null : ecLevel.toString(),
                           symbolSequence,
                           parityData);
}
 
Example 28
static DecoderResult decode(int[] codewords, String ecLevel) throws FormatException {
  StringBuilder result = new StringBuilder(codewords.length * 2);
  Charset encoding = DEFAULT_ENCODING;
  // 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:
      case BYTE_COMPACTION_MODE_LATCH_6:
        codeIndex = byteCompaction(code, codewords, encoding, codeIndex, result);
        break;
      case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
        result.append((char) codewords[codeIndex++]);
        break;
      case NUMERIC_COMPACTION_MODE_LATCH:
        codeIndex = numericCompaction(codewords, codeIndex, result);
        break;
      case ECI_CHARSET:
        CharacterSetECI charsetECI =
            CharacterSetECI.getCharacterSetECIByValue(codewords[codeIndex++]);
        encoding = Charset.forName(charsetECI.name());
        break;
      case ECI_GENERAL_PURPOSE:
        // Can't do anything with generic ECI; skip its 2 characters
        codeIndex += 2;
        break;
      case ECI_USER_DEFINED:
        // Can't do anything with user ECI; skip its 1 character
        codeIndex ++;
        break;
      case BEGIN_MACRO_PDF417_CONTROL_BLOCK:
        codeIndex = decodeMacroBlock(codewords, codeIndex, resultMetadata);
        break;
      case BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
      case MACRO_PDF417_TERMINATOR:
        // Should not see these outside a macro block
        throw FormatException.getFormatInstance();
      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;
}
 
Example 29
public static QRCode encode(String content,
                            ErrorCorrectionLevel ecLevel,
                            Map<EncodeHintType,?> hints) throws WriterException {

  // Determine what character encoding has been specified by the caller, if any
  String encoding = DEFAULT_BYTE_MODE_ENCODING;
  if (hints != null && hints.containsKey(EncodeHintType.CHARACTER_SET)) {
    encoding = hints.get(EncodeHintType.CHARACTER_SET).toString();
  }

  // Pick an encoding mode appropriate for the content. Note that this will not attempt to use
  // multiple modes / segments even if that were more efficient. Twould be nice.
  Mode mode = chooseMode(content, encoding);

  // This will store the header information, like mode and
  // length, as well as "header" segments like an ECI segment.
  BitArray headerBits = new BitArray();

  // Append ECI segment if applicable
  if (mode == Mode.BYTE && !DEFAULT_BYTE_MODE_ENCODING.equals(encoding)) {
    CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding);
    if (eci != null) {
      appendECI(eci, headerBits);
    }
  }

  // (With ECI in place,) Write the mode marker
  appendModeInfo(mode, headerBits);

  // Collect data within the main segment, separately, to count its size if needed. Don't add it to
  // main payload yet.
  BitArray dataBits = new BitArray();
  appendBytes(content, mode, dataBits, encoding);

  // Hard part: need to know version to know how many bits length takes. But need to know how many
  // bits it takes to know version. First we take a guess at version by assuming version will be
  // the minimum, 1:

  int provisionalBitsNeeded = headerBits.getSize()
      + mode.getCharacterCountBits(Version.getVersionForNumber(1))
      + dataBits.getSize();
  Version provisionalVersion = chooseVersion(provisionalBitsNeeded, ecLevel);

  // Use that guess to calculate the right version. I am still not sure this works in 100% of cases.

  int bitsNeeded = headerBits.getSize()
      + mode.getCharacterCountBits(provisionalVersion)
      + dataBits.getSize();
  Version version = chooseVersion(bitsNeeded, ecLevel);

  BitArray headerAndDataBits = new BitArray();
  headerAndDataBits.appendBitArray(headerBits);
  // Find "length" of main segment and write it
  int numLetters = mode == Mode.BYTE ? dataBits.getSizeInBytes() : content.length();
  appendLengthInfo(numLetters, version, mode, headerAndDataBits);
  // Put data together into the overall payload
  headerAndDataBits.appendBitArray(dataBits);

  Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);
  int numDataBytes = version.getTotalCodewords() - ecBlocks.getTotalECCodewords();

  // Terminate the bits properly.
  terminateBits(numDataBytes, headerAndDataBits);

  // Interleave data bits with error correction code.
  BitArray finalBits = interleaveWithECBytes(headerAndDataBits,
                                             version.getTotalCodewords(),
                                             numDataBytes,
                                             ecBlocks.getNumBlocks());

  QRCode qrCode = new QRCode();

  qrCode.setECLevel(ecLevel);
  qrCode.setMode(mode);
  qrCode.setVersion(version);

  //  Choose the mask pattern and set to "qrCode".
  int dimension = version.getDimensionForVersion();
  ByteMatrix matrix = new ByteMatrix(dimension, dimension);
  int maskPattern = chooseMaskPattern(finalBits, ecLevel, version, matrix);
  qrCode.setMaskPattern(maskPattern);

  // Build the matrix and set it to "qrCode".
  MatrixUtil.buildMatrix(finalBits, ecLevel, version, maskPattern, matrix);
  qrCode.setMatrix(matrix);

  return qrCode;
}
 
Example 30
private static void appendECI(CharacterSetECI eci, BitArray bits) {
  bits.appendBits(Mode.ECI.getBits(), 4);
  // This is correct for values up to 127, which is all we need now.
  bits.appendBits(eci.getValue(), 8);
}