Search in sources :

Example 1 with CharacterSetECI

use of com.google.zxing.common.CharacterSetECI in project weex-example by KalicyZhou.

the class DecodedBitStreamParser method decode.

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;
}
Also used : Charset(java.nio.charset.Charset) DecoderResult(com.google.zxing.common.DecoderResult) PDF417ResultMetadata(com.google.zxing.pdf417.PDF417ResultMetadata) CharacterSetECI(com.google.zxing.common.CharacterSetECI)

Example 2 with CharacterSetECI

use of com.google.zxing.common.CharacterSetECI in project weex-example by KalicyZhou.

the class DecodedBitStreamParser method decode.

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 is encoded by 4 bits
                mode = Mode.forBits(bits.readBits(4));
            }
            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);
}
Also used : BitSource(com.google.zxing.common.BitSource) ArrayList(java.util.ArrayList) DecoderResult(com.google.zxing.common.DecoderResult) CharacterSetECI(com.google.zxing.common.CharacterSetECI)

Example 3 with CharacterSetECI

use of com.google.zxing.common.CharacterSetECI in project weex-example by KalicyZhou.

the class Encoder method encode.

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;
}
Also used : Version(com.google.zxing.qrcode.decoder.Version) Mode(com.google.zxing.qrcode.decoder.Mode) BitArray(com.google.zxing.common.BitArray) CharacterSetECI(com.google.zxing.common.CharacterSetECI)

Example 4 with CharacterSetECI

use of com.google.zxing.common.CharacterSetECI in project zxing by zxing.

the class DecodedBitStreamParser method decode.

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 is encoded by 4 bits
                mode = Mode.forBits(bits.readBits(4));
            }
            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);
}
Also used : BitSource(com.google.zxing.common.BitSource) ArrayList(java.util.ArrayList) DecoderResult(com.google.zxing.common.DecoderResult) CharacterSetECI(com.google.zxing.common.CharacterSetECI)

Example 5 with CharacterSetECI

use of com.google.zxing.common.CharacterSetECI in project zxing by zxing.

the class Encoder method encode.

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;
}
Also used : Version(com.google.zxing.qrcode.decoder.Version) Mode(com.google.zxing.qrcode.decoder.Mode) BitArray(com.google.zxing.common.BitArray) CharacterSetECI(com.google.zxing.common.CharacterSetECI) WriterException(com.google.zxing.WriterException)

Aggregations

CharacterSetECI (com.google.zxing.common.CharacterSetECI)6 DecoderResult (com.google.zxing.common.DecoderResult)4 BitArray (com.google.zxing.common.BitArray)2 BitSource (com.google.zxing.common.BitSource)2 PDF417ResultMetadata (com.google.zxing.pdf417.PDF417ResultMetadata)2 Mode (com.google.zxing.qrcode.decoder.Mode)2 Version (com.google.zxing.qrcode.decoder.Version)2 Charset (java.nio.charset.Charset)2 ArrayList (java.util.ArrayList)2 WriterException (com.google.zxing.WriterException)1