/// <summary>
        ///
        /// ISO/IEC 18004:2006(E)
        /// Table 2 ¡ª Mode indicators for QR Code 2005
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="version"></param>
        /// <param name="ecLevel"></param>
        /// <returns></returns>
        internal static DecoderResult decode(sbyte[] bytes, Version version, ErrorCorrectionLevel ecLevel)
        {
            BitSource bits = new BitSource(bytes);

            System.Text.StringBuilder result = new System.Text.StringBuilder(50);
            CharacterSetECI           currentCharacterSetECI = null;
            bool fc1InEffect = false;

            System.Collections.ArrayList byteSegments = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(1));
            Mode mode   = Mode.TERMINATOR;
            int  bitLen = Mode.NUMERIC.getBitsLength(version.VersionNumber);

            if (version.VersionNumber > 1)
            {
                try
                {
                    mode = Mode.forBits(bits.readBits(bitLen));
                }
                catch (System.ArgumentException iae)
                {
                    throw ReaderException.Instance;
                }
            }
            else
            {
                mode = Mode.NUMERIC;
            }

            if (!mode.Equals(Mode.TERMINATOR))
            {
                // How many characters will follow, encoded in this mode?
                int count = bits.readBits(mode.getCharacterCountBits(version));
                if (mode.Equals(Mode.NUMERIC))
                {
                    decodeNumericSegment(bits, result, count);
                }
                else if (mode.Equals(Mode.ALPHANUMERIC))
                {
                    decodeAlphanumericSegment(bits, result, count, fc1InEffect);
                }
                else if (mode.Equals(Mode.BYTE))
                {
                    decodeByteSegment(bits, result, count, currentCharacterSetECI, byteSegments);
                }
                else if (mode.Equals(Mode.KANJI))
                {
                    decodeKanjiSegment(bits, result, count);
                }
                else
                {
                    throw ReaderException.Instance;
                }
            }

            return(new DecoderResult(bytes, result.ToString(), (byteSegments.Count == 0) ? null : byteSegments, ecLevel));
        }
 private static void decodeByteSegment(BitSource bits, System.Text.StringBuilder result, int count, CharacterSetECI currentCharacterSetECI, System.Collections.ArrayList byteSegments)
 {
     sbyte[] readBytes = new sbyte[count];
     if (count << 3 > bits.available())
     {
         throw ReaderException.Instance;
     }
     for (int i = 0; i < count; i++)
     {
         readBytes[i] = (sbyte) bits.readBits(8);
     }
     System.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 = guessEncoding(readBytes);
     }
     else
     {
         encoding = currentCharacterSetECI.EncodingName;
     }
     try
     {
         //UPGRADE_TODO: The differences in the Format  of parameters for constructor 'java.lang.String.String'  may cause compilation errors.  "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1092'"
         result.Append(System.Text.Encoding.GetEncoding(encoding).GetString(SupportClass.ToByteArray(readBytes)));
     }
     catch (System.IO.IOException)
     {
         throw ReaderException.Instance;
     }
     byteSegments.Add(SupportClass.ToByteArray(readBytes));
 }
        internal static DecoderResult decode(sbyte[] bytes, Version version, ErrorCorrectionLevel ecLevel)
        {
            BitSource bits = new BitSource(bytes);

            System.Text.StringBuilder result = new System.Text.StringBuilder(50);
            CharacterSetECI           currentCharacterSetECI = null;
            bool fc1InEffect = false;

            System.Collections.ArrayList byteSegments = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(1));
            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 (System.ArgumentException iae)
                    {
                        throw ReaderException.Instance;
                    }
                }
                if (!mode.Equals(Mode.TERMINATOR))
                {
                    if (mode.Equals(Mode.FNC1_FIRST_POSITION) || mode.Equals(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.Equals(Mode.STRUCTURED_APPEND))
                    {
                        // 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.Equals(Mode.ECI))
                    {
                        // Count doesn't apply to ECI
                        int value_Renamed = parseECIValue(bits);
                        currentCharacterSetECI = CharacterSetECI.getCharacterSetECIByValue(value_Renamed);
                        if (currentCharacterSetECI == null)
                        {
                            throw ReaderException.Instance;
                        }
                    }
                    else
                    {
                        // How many characters will follow, encoded in this mode?
                        int count = bits.readBits(mode.getCharacterCountBits(version));
                        if (mode.Equals(Mode.NUMERIC))
                        {
                            decodeNumericSegment(bits, result, count);
                        }
                        else if (mode.Equals(Mode.ALPHANUMERIC))
                        {
                            decodeAlphanumericSegment(bits, result, count, fc1InEffect);
                        }
                        else if (mode.Equals(Mode.BYTE))
                        {
                            decodeByteSegment(bits, result, count, currentCharacterSetECI, byteSegments);
                        }
                        else if (mode.Equals(Mode.KANJI))
                        {
                            decodeKanjiSegment(bits, result, count);
                        }
                        else
                        {
                            throw ReaderException.Instance;
                        }
                    }
                }
            }while (!mode.Equals(Mode.TERMINATOR));

            return(new DecoderResult(bytes, result.ToString(), (byteSegments.Count == 0)?null:byteSegments, ecLevel));
        }
        private static void  decodeByteSegment(BitSource bits, System.Text.StringBuilder result, int count, CharacterSetECI currentCharacterSetECI, System.Collections.ArrayList byteSegments)
        {
            sbyte[] readBytes = new sbyte[count];
            if (count << 3 > bits.available())
            {
                throw ReaderException.Instance;
            }
            for (int i = 0; i < count; i++)
            {
                readBytes[i] = (sbyte)bits.readBits(8);
            }
            System.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 = guessEncoding(readBytes);
            }
            else
            {
                encoding = currentCharacterSetECI.EncodingName;
            }
            try
            {
                //UPGRADE_TODO: The differences in the Format  of parameters for constructor 'java.lang.String.String'  may cause compilation errors.  "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1092'"
#if WINDOWS_PHONE
                byte[] byteArray = SupportClass.ToByteArray(readBytes);
                result.Append(System.Text.Encoding.GetEncoding(encoding).GetString(byteArray, 0, byteArray.Length));
#else
                result.Append(System.Text.Encoding.GetEncoding(encoding).GetString(SupportClass.ToByteArray(readBytes)));
#endif
            }
            catch (System.IO.IOException uce)
            {
                throw ReaderException.Instance;
            }
            byteSegments.Add(SupportClass.ToByteArray(readBytes));
        }
		private static void  appendECI(CharacterSetECI eci, BitVector bits)
		{
			bits.appendBits(Mode.ECI.Bits, 4);
			// This is correct for values up to 127, which is all we need now.
			bits.appendBits(eci.Value, 8);
		}
Beispiel #6
0
        internal static void encode(System.String content, ErrorCorrectionLevelInternal m_EcLevelInternal, System.Collections.Hashtable hints, QRCodeInternal qrCodeInternal)
        {
            System.String encoding = hints == null ? null : (System.String)hints[EncodeHintType.CHARACTER_SET];
            if (encoding == null)
            {
                encoding = DEFAULT_BYTE_MODE_ENCODING;
            }

            // Step 1: Choose the mode (encoding).
            Mode mode = chooseMode(content, encoding);

            // Step 2: Append "bytes" into "dataBits" in appropriate encoding.
            BitVector dataBits = new BitVector();

            appendBytes(content, mode, dataBits, encoding);
            // Step 3: Initialize QR code that can contain "dataBits".
            int numInputBytes = dataBits.sizeInBytes();

            initQRCode(numInputBytes, m_EcLevelInternal, mode, qrCodeInternal);

            // Step 4: Build another bit vector that contains header and data.
            BitVector headerAndDataBits = new BitVector();

            // Step 4.5: Append ECI message if applicable
            if (mode == Mode.BYTE && !DEFAULT_BYTE_MODE_ENCODING.Equals(encoding))
            {
                CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding);
                if (eci != null)
                {
                    appendECI(eci, headerAndDataBits);
                }
            }

            appendModeInfo(mode, headerAndDataBits);

            int numLetters = mode.Equals(Mode.BYTE) ? dataBits.sizeInBytes() : content.Length;

            appendLengthInfo(numLetters, qrCodeInternal.Version, mode, headerAndDataBits);
            headerAndDataBits.appendBitVector(dataBits);

            // Step 5: Terminate the bits properly.
            terminateBits(qrCodeInternal.NumDataBytes, headerAndDataBits);

            // Step 6: Interleave data bits with error correction code.
            BitVector finalBits = new BitVector();

            interleaveWithECBytes(headerAndDataBits, qrCodeInternal.NumTotalBytes, qrCodeInternal.NumDataBytes, qrCodeInternal.NumRSBlocks, finalBits);

            // Step 7: Choose the mask pattern and set to "QRCodeInternal".
            ByteMatrix matrix = new ByteMatrix(qrCodeInternal.MatrixWidth, qrCodeInternal.MatrixWidth);

            qrCodeInternal.MaskPattern = chooseMaskPattern(finalBits, qrCodeInternal.EcLevelInternal, qrCodeInternal.Version, matrix);

            // Step 8.  Build the matrix and set it to "QRCodeInternal".
            MatrixUtil.buildMatrix(finalBits, qrCodeInternal.EcLevelInternal, qrCodeInternal.Version, qrCodeInternal.MaskPattern, matrix);
            qrCodeInternal.Matrix = matrix;
            // Step 9.  Make sure we have a valid QR Code.
            if (!qrCodeInternal.Valid)
            {
                throw new WriterException("Invalid QR code: " + qrCodeInternal.ToString());
            }
        }
Beispiel #7
0
 internal static void appendECI(CharacterSetECI eci, BitVector bits)
 {
     bits.appendBits(Mode.ECI.Bits, 4);
     // This is correct for values up to 127, which is all we need now.
     bits.appendBits(eci.Value, 8);
 }