/**
   * 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) {
      encoding = DEFAULT_ENCODING;
    } else if (!DEFAULT_ENCODING.equals(encoding)) {
      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
    if (compaction == Compaction.TEXT) {
      encodeText(msg, p, len, sb, textSubMode);

    } else if (compaction == Compaction.BYTE) {
      byte[] bytes = msg.getBytes(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 {
            int b = determineConsecutiveBinaryCount(msg, p, encoding);
            if (b == 0) {
              b = 1;
            }
            byte[] bytes = msg.substring(p, p + b).getBytes(encoding);
            if (bytes.length == 1 && encodingMode == TEXT_COMPACTION) {
              // Switch for one byte (instead of latch)
              encodeBinary(bytes, 0, 1, TEXT_COMPACTION, sb);
            } else {
              // Mode latch performed by encodeBinary()
              encodeBinary(bytes, 0, bytes.length, encodingMode, sb);
              encodingMode = BYTE_COMPACTION;
              textSubMode = SUBMODE_ALPHA; // Reset after latch
            }
            p += b;
          }
        }
      }
    }

    return sb.toString();
  }
Example #2
0
 private static void a(CharacterSetECI characterseteci, BitArray bitarray)
 {
     bitarray.appendBits(Mode.ECI.getBits(), 4);
     bitarray.appendBits(characterseteci.getValue(), 8);
 }