示例#1
0
        private void ZXEncode(string content, int option)
        {
            System.String encoding = QRCodeConstantVariable.DefaultEncoding;
            ErrorCorrectionLevelInternal m_EcLevelInternal = ErrorCorrectionLevelInternal.H;
            QRCodeInternal qrCodeInternal = new QRCodeInternal();

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

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

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

            EncoderInternal.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 && !QRCodeConstantVariable.DefaultEncoding.Equals(encoding))
            {
                CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding);
                if (eci != null)
                {
                    EncoderInternal.appendECI(eci, headerAndDataBits);
                }
            }

            EncoderInternal.appendModeInfo(mode, headerAndDataBits);

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

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

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

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

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

            if (option == 3)
            {
                return;
            }

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

            qrCodeInternal.MaskPattern = EncoderInternal.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;
        }
示例#2
0
        /// <summary> Append length info. On success, store the result in "bits".</summary>
        internal static void appendLengthInfo(int numLetters, int version, Mode mode, BitVector bits)
        {
            int numBits = mode.getCharacterCountBits(Version.getVersionForNumber(version));

            if (numLetters > ((1 << numBits) - 1))
            {
                throw new WriterException(numLetters + "is bigger than" + ((1 << numBits) - 1));
            }
            bits.appendBits(numLetters, numBits);
        }
        /// <summary>
        /// Combine Gma.QrCodeNet.Encoding input recognition method and version control method
        /// with legacy code. To create expected answer.
        /// This is base on assume Gma.QrCodeNet.Encoding input recognition and version control sometime
        /// give different result as legacy code.
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        internal static BitVector DataEncodeUsingReferenceImplementation(string content, ErrorCorrectionLevel ecLevel, out QRCodeInternal qrInternal)
        {
            if (string.IsNullOrEmpty(content))
            {
                throw new ArgumentException("input string content can not be null or empty");
            }

            //Choose mode
            RecognitionStruct recognitionResult = InputRecognise.Recognise(content);
            string            encodingName      = recognitionResult.EncodingName;
            Mode mode = ConvertMode(recognitionResult.Mode);

            //append byte to databits
            BitVector dataBits = new BitVector();

            EncoderInternal.appendBytes(content, mode, dataBits, encodingName);

            int dataBitsLength            = dataBits.size();
            VersionControlStruct vcStruct =
                VersionControl.InitialSetup(dataBitsLength, recognitionResult.Mode, ecLevel, recognitionResult.EncodingName);
            //ECI
            BitVector headerAndDataBits = new BitVector();
            string    defaultByteMode   = "iso-8859-1";

            if (mode == Mode.BYTE && !defaultByteMode.Equals(encodingName))
            {
                CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encodingName);
                if (eci != null)
                {
                    EncoderInternal.appendECI(eci, headerAndDataBits);
                }
            }
            //Mode
            EncoderInternal.appendModeInfo(mode, headerAndDataBits);
            //Char info
            int numLetters = mode.Equals(Mode.BYTE)?dataBits.sizeInBytes():content.Length;

            EncoderInternal.appendLengthInfo(numLetters, vcStruct.VersionDetail.Version, mode, headerAndDataBits);
            //Combine with dataBits
            headerAndDataBits.appendBitVector(dataBits);

            // Terminate the bits properly.
            EncoderInternal.terminateBits(vcStruct.VersionDetail.NumDataBytes, headerAndDataBits);

            qrInternal                 = new QRCodeInternal();
            qrInternal.Version         = vcStruct.VersionDetail.Version;
            qrInternal.MatrixWidth     = vcStruct.VersionDetail.MatrixWidth;
            qrInternal.EcLevelInternal = ErrorCorrectionLevelConverter.ToInternal(ecLevel);
            qrInternal.NumTotalBytes   = vcStruct.VersionDetail.NumTotalBytes;
            qrInternal.NumDataBytes    = vcStruct.VersionDetail.NumDataBytes;
            qrInternal.NumRSBlocks     = vcStruct.VersionDetail.NumECBlocks;
            return(headerAndDataBits);
        }
示例#4
0
 public QRCodeInternal()
 {
     mode = null;
     m_EcLevelInternal = null;
     version           = -1;
     matrixWidth       = -1;
     maskPattern       = -1;
     numTotalBytes     = -1;
     numDataBytes      = -1;
     numECBytes        = -1;
     numRSBlocks       = -1;
     matrix            = null;
 }
示例#5
0
 public QRCode()
 {
     mode = null;
     ecLevel = null;
     version = -1;
     matrixWidth = -1;
     maskPattern = -1;
     numTotalBytes = -1;
     numDataBytes = -1;
     numECBytes = -1;
     numRSBlocks = -1;
     matrix = null;
 }
示例#6
0
 /// <summary> Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits".</summary>
 internal static void appendBytes(System.String content, Mode mode, BitVector bits, System.String encoding)
 {
     if (mode.Equals(Mode.NUMERIC))
     {
         appendNumericBytes(content, bits);
     }
     else if (mode.Equals(Mode.ALPHANUMERIC))
     {
         appendAlphanumericBytes(content, bits);
     }
     else if (mode.Equals(Mode.BYTE))
     {
         append8BitBytes(content, bits, encoding);
     }
     else if (mode.Equals(Mode.KANJI))
     {
         appendKanjiBytes(content, bits);
     }
     else
     {
         throw new WriterException("Invalid mode: " + mode);
     }
 }
示例#7
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());
            }
        }
示例#8
0
 /// <summary> Append mode info. On success, store the result in "bits".</summary>
 internal static void appendModeInfo(Mode mode, BitVector bits)
 {
     bits.appendBits(mode.Bits, 4);
 }
示例#9
0
        /// <summary> Initialize "QRCodeInternal" according to "numInputBytes", "m_EcLevelInternal", and "mode". On success,
        /// modify "QRCodeInternal".
        /// </summary>
        internal static void initQRCode(int numInputBytes, ErrorCorrectionLevelInternal m_EcLevelInternal, Mode mode, QRCodeInternal qrCodeInternal)
        {
            qrCodeInternal.EcLevelInternal = m_EcLevelInternal;
            qrCodeInternal.Mode            = mode;

            // In the following comments, we use numbers of Version 7-H.
            for (int versionNum = 1; versionNum <= 40; versionNum++)
            {
                Version version = Version.getVersionForNumber(versionNum);
                // numBytes = 196
                int numBytes = version.TotalCodewords;
                // getNumECBytes = 130
                Version.ECBlocks ecBlocks = version.getECBlocksForLevel(m_EcLevelInternal);
                int numEcBytes            = ecBlocks.TotalECCodewords;
                // getNumRSBlocks = 5
                int numRSBlocks = ecBlocks.NumBlocks;
                // getNumDataBytes = 196 - 130 = 66
                int numDataBytes = numBytes - numEcBytes;
                // We want to choose the smallest version which can contain data of "numInputBytes" + some
                // extra bits for the header (mode info and length info). The header can be three bytes
                // (precisely 4 + 16 bits) at most. Hence we do +3 here.
                if (numDataBytes >= numInputBytes + 3)
                {
                    // Yay, we found the proper rs block info!
                    qrCodeInternal.Version       = versionNum;
                    qrCodeInternal.NumTotalBytes = numBytes;
                    qrCodeInternal.NumDataBytes  = numDataBytes;
                    qrCodeInternal.NumRSBlocks   = numRSBlocks;
                    // getNumECBytes = 196 - 66 = 130
                    qrCodeInternal.NumECBytes = numEcBytes;
                    // matrix width = 21 + 6 * 4 = 45
                    qrCodeInternal.MatrixWidth = version.DimensionForVersion;
                    return;
                }
            }
            throw new WriterException("Cannot find proper rs block info (input data too big?)");
        }
示例#10
0
		/// <summary> Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits".</summary>
		internal static void  appendBytes(System.String content, Mode mode, BitVector bits, System.String encoding)
		{
			if (mode.Equals(Mode.NUMERIC))
			{
				appendNumericBytes(content, bits);
			}
			else if (mode.Equals(Mode.ALPHANUMERIC))
			{
				appendAlphanumericBytes(content, bits);
			}
			else if (mode.Equals(Mode.BYTE))
			{
				append8BitBytes(content, bits, encoding);
			}
			else if (mode.Equals(Mode.KANJI))
			{
				appendKanjiBytes(content, bits);
			}
			else
			{
				throw new WriterException("Invalid mode: " + mode);
			}
		}
示例#11
0
		/// <summary> Append length info. On success, store the result in "bits".</summary>
		internal static void  appendLengthInfo(int numLetters, int version, Mode mode, BitVector bits)
		{
			int numBits = mode.getCharacterCountBits(Version.getVersionForNumber(version));
			if (numLetters > ((1 << numBits) - 1))
			{
				throw new WriterException(numLetters + "is bigger than" + ((1 << numBits) - 1));
			}
			bits.appendBits(numLetters, numBits);
		}
示例#12
0
		/// <summary> Append mode info. On success, store the result in "bits".</summary>
		internal static void  appendModeInfo(Mode mode, BitVector bits)
		{
			bits.appendBits(mode.Bits, 4);
		}
示例#13
0
		/// <summary> Initialize "QRCodeInternal" according to "numInputBytes", "m_EcLevelInternal", and "mode". On success,
		/// modify "QRCodeInternal".
		/// </summary>
		internal static void  initQRCode(int numInputBytes, ErrorCorrectionLevelInternal m_EcLevelInternal, Mode mode, QRCodeInternal qrCodeInternal)
		{
			qrCodeInternal.EcLevelInternal = m_EcLevelInternal;
			qrCodeInternal.Mode = mode;
			
			// In the following comments, we use numbers of Version 7-H.
			for (int versionNum = 1; versionNum <= 40; versionNum++)
			{
				Version version = Version.getVersionForNumber(versionNum);
				// numBytes = 196
				int numBytes = version.TotalCodewords;
				// getNumECBytes = 130
				Version.ECBlocks ecBlocks = version.getECBlocksForLevel(m_EcLevelInternal);
				int numEcBytes = ecBlocks.TotalECCodewords;
				// getNumRSBlocks = 5
				int numRSBlocks = ecBlocks.NumBlocks;
				// getNumDataBytes = 196 - 130 = 66
				int numDataBytes = numBytes - numEcBytes;
				// We want to choose the smallest version which can contain data of "numInputBytes" + some
				// extra bits for the header (mode info and length info). The header can be three bytes
				// (precisely 4 + 16 bits) at most. Hence we do +3 here.
				if (numDataBytes >= numInputBytes + 3)
				{
					// Yay, we found the proper rs block info!
					qrCodeInternal.Version = versionNum;
					qrCodeInternal.NumTotalBytes = numBytes;
					qrCodeInternal.NumDataBytes = numDataBytes;
					qrCodeInternal.NumRSBlocks = numRSBlocks;
					// getNumECBytes = 196 - 66 = 130
					qrCodeInternal.NumECBytes = numEcBytes;
					// matrix width = 21 + 6 * 4 = 45
					qrCodeInternal.MatrixWidth = version.DimensionForVersion;
					return ;
				}
			}
			throw new WriterException("Cannot find proper rs block info (input data too big?)");
		}
示例#14
0
 public void setMode(Mode value)
 {
     mode = value;
 }
示例#15
0
 // Append mode info. On success, store the result in "bits" and return true. On error, return
 // false.
 static void appendModeInfo(Mode mode, BitVector bits)
 {
     bits.appendBits(mode.getBits(), 4);
 }
示例#16
0
        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));
        }