示例#1
0
文件: ECI.cs 项目: zyj0021/ZXing.Net
 /// <param name="val">ECI value</param>
 /// <returns><see cref="ECI"/> representing ECI of given value, or null if it is legal but unsupported</returns>
 /// <throws>ArgumentException if ECI value is invalid </throws>
 public static ECI getECIByValue(int val)
 {
     if (val < 0 || val > 999999)
     {
         throw new System.ArgumentException("Bad ECI value: " + val);
     }
     if (val < 900)
     {
         // Character set ECIs use 000000 - 000899
         return(CharacterSetECI.getCharacterSetECIByValue(val));
     }
     return(null);
 }
示例#2
0
            public bool AppendECI(int value)
            {
                encodeCurrentBytesIfAny();
                CharacterSetECI characterSetECI = CharacterSetECI.getCharacterSetECIByValue(value);

                if (characterSetECI == null)
                {
                    return(false);
                    //throw FormatException.getFormatInstance(new RuntimeException("Unsupported ECI value " + value));
                }
                currentCharset = CharacterSetECI.getEncoding(characterSetECI);
                return(true);
            }
示例#3
0
 /// <param name="value">ECI value
 /// </param>
 /// <returns> {@link ECI} representing ECI of given value, or null if it is legal but unsupported
 /// </returns>
 /// <throws>  IllegalArgumentException if ECI value is invalid </throws>
 internal static ECI getECIByValue(int value_Renamed)
 {
     if (value_Renamed < 0 || value_Renamed > 999999)
     {
         throw new System.ArgumentException("Bad ECI value: " + value_Renamed);
     }
     if (value_Renamed < 900)
     {
         // Character set ECIs use 000000 - 000899
         return(CharacterSetECI.getCharacterSetECIByValue(value_Renamed));
     }
     return(null);
 }
示例#4
0
        /// <summary>
        /// Gets the string encoded in the aztec code bits
        /// </summary>
        /// <param name="correctedBits">The corrected bits.</param>
        /// <returns>the decoded string</returns>
        private static String getEncodedData(bool[] correctedBits)
        {
            var endIndex   = correctedBits.Length;
            var latchTable = Table.UPPER; // table most recently latched to
            var shiftTable = Table.UPPER; // table to use for the next read
            var strTable   = UPPER_TABLE;
            var index      = 0;


            // Final decoded string result
            // (correctedBits-5) / 4 is an upper bound on the size (all-digit result)
            var result = new StringBuilder((correctedBits.Length - 5) / 4);

            // Intermediary buffer of decoded bytes, which is decoded into a string and flushed
            // when character encoding changes (ECI) or input ends.
            using (var decodedBytes = new System.IO.MemoryStream())
            {
                var encoding = DEFAULT_ENCODING;

                while (index < endIndex)
                {
                    if (shiftTable == Table.BINARY)
                    {
                        if (endIndex - index < 5)
                        {
                            break;
                        }
                        int length = readCode(correctedBits, index, 5);
                        index += 5;
                        if (length == 0)
                        {
                            if (endIndex - index < 11)
                            {
                                break;
                            }
                            length = readCode(correctedBits, index, 11) + 31;
                            index += 11;
                        }
                        for (int charCount = 0; charCount < length; charCount++)
                        {
                            if (endIndex - index < 8)
                            {
                                index = endIndex; // Force outer loop to exit
                                break;
                            }
                            int code = readCode(correctedBits, index, 8);
                            decodedBytes.WriteByte((byte)code);
                            index += 8;
                        }
                        // Go back to whatever mode we had been in
                        shiftTable = latchTable;
                        strTable   = codeTables[shiftTable];
                    }
                    else
                    {
                        int size = shiftTable == Table.DIGIT ? 4 : 5;
                        if (endIndex - index < size)
                        {
                            break;
                        }
                        int code = readCode(correctedBits, index, size);
                        index += size;
                        String str = getCharacter(strTable, code);
                        if ("FLG(n)".Equals(str))
                        {
                            if (endIndex - index < 3)
                            {
                                break;
                            }
                            int n = readCode(correctedBits, index, 3);
                            index += 3;
                            //  flush bytes, FLG changes state
                            if (decodedBytes.Length > 0)
                            {
                                var byteArray = decodedBytes.ToArray();
                                result.Append(encoding.GetString(byteArray, 0, byteArray.Length));
                                decodedBytes.SetLength(0);
                            }
                            switch (n)
                            {
                            case 0:
                                result.Append((char)29);      // translate FNC1 as ASCII 29
                                break;

                            case 7:
                                throw new FormatException("FLG(7) is reserved and illegal");

                            default:
                                // ECI is decimal integer encoded as 1-6 codes in DIGIT mode
                                int eci = 0;
                                if (endIndex - index < 4 * n)
                                {
                                    break;
                                }
                                while (n-- > 0)
                                {
                                    int nextDigit = readCode(correctedBits, index, 4);
                                    index += 4;
                                    if (nextDigit < 2 || nextDigit > 11)
                                    {
                                        throw new FormatException("Not a decimal digit");
                                    }
                                    eci = eci * 10 + (nextDigit - 2);
                                }
                                CharacterSetECI charsetECI = CharacterSetECI.getCharacterSetECIByValue(eci);
                                encoding = CharacterSetECI.getEncoding(charsetECI);
                                if (encoding == null)
                                {
                                    throw new FormatException("Encoding for ECI " + eci + " can't be resolved");
                                }
                                break;
                            }
                            // Go back to whatever mode we had been in
                            shiftTable = latchTable;
                            strTable   = codeTables[shiftTable];
                        }
                        else if (str.StartsWith("CTRL_"))
                        {
                            // Table changes
                            // ISO/IEC 24778:2008 prescribes ending a shift sequence in the mode from which it was invoked.
                            // That's including when that mode is a shift.
                            // Our test case dlusbs.png for issue #642 exercises that.
                            latchTable = shiftTable;  // Latch the current mode, so as to return to Upper after U/S B/S
                            shiftTable = getTable(str[5]);
                            strTable   = codeTables[shiftTable];
                            if (str[6] == 'L')
                            {
                                latchTable = shiftTable;
                            }
                        }
                        else
                        {
                            // Though stored as a table of strings for convenience, codes actually represent 1 or 2 *bytes*.
#if (PORTABLE || NETSTANDARD1_0 || NETSTANDARD1_1 || WINDOWS_PHONE || NETFX_CORE || SILVERLIGHT)
                            var b = StringUtils.PLATFORM_DEFAULT_ENCODING_T.GetBytes(str);
#else
                            var b = Encoding.ASCII.GetBytes(str);
#endif
                            decodedBytes.Write(b, 0, b.Length);
                            // Go back to whatever mode we had been in
                            shiftTable = latchTable;
                            strTable   = codeTables[shiftTable];
                        }
                    }
                }

                if (decodedBytes.Length > 0)
                {
                    var byteArray = decodedBytes.ToArray();
                    result.Append(encoding.GetString(byteArray, 0, byteArray.Length));
                }
            }
            return(result.ToString());
        }
        internal static DecoderResult decode(byte[] bytes,
                                             Version version,
                                             ErrorCorrectionLevel ecLevel,
                                             IDictionary <DecodeHintType, object> hints)
        {
            var bits           = new BitSource(bytes);
            var result         = new StringBuilder(50);
            var byteSegments   = new List <byte[]> (1);
            var symbolSequence = -1;
            var parityData     = -1;

            try {
                CharacterSetECI currentCharacterSetECI = null;
                bool            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
                    {
                        try {
                            mode = Mode.forBits(bits.readBits(4));                               // mode is encoded by 4 bits
                        } catch (ArgumentException) {
                            return(null);
                        }
                    }
                    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)
                            {
                                return(null);
                            }
                            // not really supported; but 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)
                            {
                                return(null);
                            }
                        }
                        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)
                                {
                                    if (!decodeHanziSegment(bits, result, countHanzi))
                                    {
                                        return(null);
                                    }
                                }
                            }
                            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)
                                {
                                    if (!decodeNumericSegment(bits, result, count))
                                    {
                                        return(null);
                                    }
                                }
                                else if (mode == Mode.ALPHANUMERIC)
                                {
                                    if (!decodeAlphanumericSegment(bits, result, count, fc1InEffect))
                                    {
                                        return(null);
                                    }
                                }
                                else if (mode == Mode.BYTE)
                                {
                                    if (!decodeByteSegment(bits, result, count, currentCharacterSetECI, byteSegments, hints))
                                    {
                                        return(null);
                                    }
                                }
                                else if (mode == Mode.KANJI)
                                {
                                    if (!decodeKanjiSegment(bits, result, count))
                                    {
                                        return(null);
                                    }
                                }
                                else
                                {
                                    return(null);
                                }
                            }
                        }
                    }
                } while (mode != Mode.TERMINATOR);
            } catch (ArgumentException) {
                // from readBits() calls
                return(null);
            }

#if WindowsCE
            var resultString = result.ToString().Replace("\n", "\r\n");
#else
            var resultString = result.ToString().Replace("\r\n", "\n").Replace("\n", Environment.NewLine);
#endif
            return(new DecoderResult(bytes,
                                     resultString,
                                     byteSegments.Count == 0 ? null : byteSegments,
                                     ecLevel == null ? null : ecLevel.ToString(),
                                     symbolSequence, parityData));
        }
示例#6
0
        internal static DecoderResult decode(int[] codewords, String ecLevel)
        {
            var result = new StringBuilder(codewords.Length * 2);
            // Get compaction mode
            int      codeIndex      = 1;
            int      code           = codewords[codeIndex++];
            var      resultMetadata = new PDF417ResultMetadata();
            Encoding encoding       = null;

            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 ?? (encoding = getEncoding(PDF417HighLevelEncoder.DEFAULT_ENCODING_NAME)), 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:
                    var charsetECI = CharacterSetECI.getCharacterSetECIByValue(codewords[codeIndex++]);
                    encoding = getEncoding(charsetECI.EncodingName);
                    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
                    return(null);

                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 < 0)
                {
                    return(null);
                }
                if (codeIndex < codewords.Length)
                {
                    code = codewords[codeIndex++];
                }
                else
                {
                    return(null);
                }
            }

            if (result.Length == 0)
            {
                return(null);
            }

            var decoderResult = new DecoderResult(null, result.ToString(), null, ecLevel);

            decoderResult.Other = resultMetadata;
            return(decoderResult);
        }
示例#7
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: static com.google.zxing.common.DecoderResult decode(byte[] bytes, Version version, ErrorCorrectionLevel ecLevel, java.util.Map<com.google.zxing.DecodeHintType,?> hints) throws com.google.zxing.FormatException
        internal static DecoderResult decode(sbyte[] bytes, Version version, ErrorCorrectionLevel ecLevel, IDictionary <DecodeHintType, object> hints)
        {
            BitSource       bits         = new BitSource(bytes);
            StringBuilder   result       = new StringBuilder(50);
            IList <sbyte[]> byteSegments = new List <sbyte[]>(1);

            try
            {
                CharacterSetECI currentCharacterSetECI = null;
                bool            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.FormatInstance;
                            }
                            // not really supported; all we do is ignore it
                            // Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue
                            bits.readBits(16);
                        }
                        else if (mode == Mode.ECI)
                        {
                            // Count doesn't apply to ECI
                            int value = parseECIValue(bits);
                            currentCharacterSetECI = CharacterSetECI.getCharacterSetECIByValue(value);
                            if (currentCharacterSetECI == null)
                            {
                                throw FormatException.FormatInstance;
                            }
                        }
                        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.FormatInstance;
                                }
                            }
                        }
                    }
                } while (mode != Mode.TERMINATOR);
            }
            catch (System.ArgumentException iae)
            {
                // from readBits() calls
                throw FormatException.FormatInstance;
            }

            return(new DecoderResult(bytes, result.ToString(), byteSegments.Count == 0 ? null : byteSegments, ecLevel == null ? null : ecLevel.ToString()));
        }