类com.google.zxing.common.CharacterSetECI源码实例Demo

下面列出了怎么用com.google.zxing.common.CharacterSetECI的API类实例代码及写法,或者点击链接到github查看源代码。

源代码1 项目: ScreenCapture   文件: DecodedBitStreamParser.java
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);
}
 
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);
}
 
源代码3 项目: QrCodeScanner   文件: DecodedBitStreamParser.java
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);
}
 
源代码4 项目: ZXing-Orient   文件: DecodedBitStreamParser.java
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);
}
 
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);
}
 
源代码6 项目: weex   文件: DecodedBitStreamParser.java
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);
}
 
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);
}
 
源代码8 项目: reacteu-app   文件: DecodedBitStreamParser.java
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);
}
 
源代码9 项目: MiBandDecompiled   文件: m.java
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);
}
 
源代码10 项目: RipplePower   文件: DecodedBitStreamParser.java
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);
}
 
源代码11 项目: Telegram-FOSS   文件: DecodedBitStreamParser.java
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);
}
 
源代码12 项目: barterli_android   文件: DecodedBitStreamParser.java
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);
}
 
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);
}
 
源代码14 项目: Telegram   文件: DecodedBitStreamParser.java
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);
}
 
源代码15 项目: ScreenCapture   文件: Encoder.java
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;
}
 
源代码16 项目: ScreenCapture   文件: Encoder.java
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);
}
 
源代码17 项目: ScreenCapture   文件: DecodedBitStreamParser.java
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);
}
 
源代码18 项目: Tesseract-OCR-Scanner   文件: Encoder.java
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;
}
 
源代码19 项目: Tesseract-OCR-Scanner   文件: Encoder.java
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);
}
 
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);
}
 
源代码21 项目: QrCodeScanner   文件: Encoder.java
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;
}
 
源代码22 项目: QrCodeScanner   文件: Encoder.java
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);
}
 
源代码23 项目: QrCodeScanner   文件: DecodedBitStreamParser.java
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);
}
 
源代码24 项目: ZXing-Orient   文件: PDF417HighLevelEncoder.java
/**
 * 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();
}
 
源代码25 项目: ZXing-Orient   文件: Encoder.java
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;
}
 
源代码26 项目: ZXing-Orient   文件: Encoder.java
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);
}
 
源代码27 项目: ZXing-Orient   文件: DecodedBitStreamParser.java
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);
}
 
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;
}
 
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;
}
 
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);
}
 
 类所在包
 同包方法