private FormatInformation(int formatInfo)
 {
     // Bits 3,4
     errorCorrectionLevel = ErrorCorrectionLevel.forBits((formatInfo >> 3) & 0x03);
     // Bottom 3 bits
     dataMask = (sbyte) (formatInfo & 0x07);
 }
Beispiel #2
0
		public static VersionTableTestProperties GetVersionInfo(int versionNum, ErrorCorrectionLevel level)
		{
			Version version = VersionTable.GetVersionByNum(versionNum);
			int totalNumCodewords = version.TotalCodewords;
			ErrorCorrectionBlocks ecBlocks = version.GetECBlocksByLevel(level);
			int numECCodewords = ecBlocks.NumErrorCorrectionCodewards;
			string ecBlockString = ErrorCorrectionBlocksToString(ecBlocks);
			
			return new VersionTableTestProperties(versionNum, totalNumCodewords, level, numECCodewords, ecBlockString);
			
		}
Beispiel #3
0
 public QRCode()
 {
     mode = null;
     ecLevel = null;
     version = -1;
     matrixWidth = -1;
     maskPattern = -1;
     numTotalBytes = -1;
     numDataBytes = -1;
     numECBytes = -1;
     numRSBlocks = -1;
     matrix = null;
 }
 internal static ErrorCorrectionLevelInternal ToInternal(ErrorCorrectionLevel level)
 {
     switch (level)
     {
         case ErrorCorrectionLevel.L:
             return ErrorCorrectionLevelInternal.L;
         case ErrorCorrectionLevel.M:
             return ErrorCorrectionLevelInternal.M;
         case ErrorCorrectionLevel.Q:
             return ErrorCorrectionLevelInternal.Q;
         case ErrorCorrectionLevel.H:
             return ErrorCorrectionLevelInternal.H;
     }
     throw new NotSupportedException(string.Format("Error correction level {0} is not supported.", level));
 }
		/// <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;
        }
Beispiel #6
0
		private static ErrorCorrectionLevelInternal ECLevelConvert(ErrorCorrectionLevel levelValue)
		{
			switch(levelValue)
			{
				case ErrorCorrectionLevel.L:
					return ErrorCorrectionLevelInternal.L;
				case ErrorCorrectionLevel.M:
					return ErrorCorrectionLevelInternal.M;
				case ErrorCorrectionLevel.Q:
					return ErrorCorrectionLevelInternal.Q;
				case ErrorCorrectionLevel.H:
					return ErrorCorrectionLevelInternal.H;
				default:
					throw new InvalidOperationException(string.Format("ErrorCorrection level {0} not correct.", levelValue));
			}
		}
        public static BitMatrix Encode(string content, ErrorCorrectionLevel ecLevel)
        {
			QRCodeInternal qrInternal;
			BitVector headerAndDataBits = DataEncodeUsingReferenceImplementation(content, ecLevel, out qrInternal);
			
			// Step 6: Interleave data bits with error correction code.
			BitVector finalBits = new BitVector();
			EncoderInternal.interleaveWithECBytes(headerAndDataBits, qrInternal.NumTotalBytes, qrInternal.NumDataBytes, qrInternal.NumRSBlocks, finalBits);
			
			// Step 7: Choose the mask pattern and set to "QRCodeInternal".
			ByteMatrix matrix = new ByteMatrix(qrInternal.MatrixWidth, qrInternal.MatrixWidth);
			int MaskPattern = EncoderInternal.chooseMaskPattern(finalBits, qrInternal.EcLevelInternal, qrInternal.Version, matrix);
			
			// Step 8.  Build the matrix and set it to "QRCodeInternal".
			MatrixUtil.buildMatrix(finalBits, qrInternal.EcLevelInternal, qrInternal.Version, MaskPattern, matrix);
			return matrix.ToBitMatrix();
        }
Beispiel #8
0
        /**
         * <p>Decodes a QR Code represented as a {@link BitMatrix}. A 1 or "true" is taken to mean a black module.</p>
         *
         * @param bits booleans representing white/black QR Code modules
         * @return text and bytes encoded within the QR Code
         * @throws ReaderException if the QR Code cannot be decoded
         */
        public DecoderResult decode(BitMatrix bits)
        {
            try{
                // Construct a parser and read version, error-correction level
                BitMatrixParser      parser  = new BitMatrixParser(bits);
                Version              version = parser.readVersion();
                ErrorCorrectionLevel ecLevel = parser.readFormatInformation().getErrorCorrectionLevel();

                // Read codewords
                sbyte[] codewords = parser.readCodewords();
                // Separate into data blocks
                DataBlock[] dataBlocks = DataBlock.getDataBlocks(codewords, version, ecLevel);

                // Count total number of data bytes
                int totalBytes = 0;
                for (int i = 0; i < dataBlocks.Length; i++)
                {
                    totalBytes += dataBlocks[i].NumDataCodewords;
                }
                sbyte[] resultBytes  = new sbyte[totalBytes];
                int     resultOffset = 0;

                // Error-correct and copy data blocks together into a stream of bytes
                for (int j = 0; j < dataBlocks.Length; j++)
                {
                    DataBlock dataBlock        = dataBlocks[j];
                    sbyte[]   codewordBytes    = dataBlock.Codewords;
                    int       numDataCodewords = dataBlock.NumDataCodewords;
                    correctErrors(codewordBytes, numDataCodewords);
                    for (int i = 0; i < numDataCodewords; i++)
                    {
                        resultBytes[resultOffset++] = codewordBytes[i];
                    }
                }

                // Decode the contents of that stream of bytes
                string sResult = DecodedBitStreamParser.decode(resultBytes, version);
                return(new DecoderResult(resultBytes, sResult, null));
            }catch (Exception e) {
                throw new ReaderException(e.Message);
            }
        }
Beispiel #9
0
        /// <summary>
        /// <p>Decodes a QR Code represented as a <seealso cref="BitMatrix"/>. A 1 or "true" is taken to mean a black module.</p>
        /// </summary>
        /// <param name="bits"> booleans representing white/black QR Code modules </param>
        /// <returns> text and bytes encoded within the QR Code </returns>
        /// <exception cref="FormatException"> if the QR Code cannot be decoded </exception>
        /// <exception cref="ChecksumException"> if error correction fails </exception>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public com.google.zxing.common.DecoderResult decode(com.google.zxing.common.BitMatrix bits, java.util.Map<com.google.zxing.DecodeHintType,?> hints) throws com.google.zxing.FormatException, com.google.zxing.ChecksumException
        public DecoderResult decode(BitMatrix bits, IDictionary <DecodeHintType, object> hints)
        {
            // Construct a parser and read version, error-correction level
            BitMatrixParser      parser  = new BitMatrixParser(bits);
            Version              version = parser.readVersion();
            ErrorCorrectionLevel ecLevel = parser.readFormatInformation().ErrorCorrectionLevel;

            // Read codewords
            sbyte[] codewords = parser.readCodewords();
            // Separate into data blocks
            DataBlock[] dataBlocks = DataBlock.getDataBlocks(codewords, version, ecLevel);

            // Count total number of data bytes
            int totalBytes = 0;

            foreach (DataBlock dataBlock in dataBlocks)
            {
                totalBytes += dataBlock.NumDataCodewords;
            }
            sbyte[] resultBytes  = new sbyte[totalBytes];
            int     resultOffset = 0;

            // Error-correct and copy data blocks together into a stream of bytes
            foreach (DataBlock dataBlock in dataBlocks)
            {
                sbyte[] codewordBytes    = dataBlock.Codewords;
                int     numDataCodewords = dataBlock.NumDataCodewords;
                correctErrors(codewordBytes, numDataCodewords);
                for (int i = 0; i < numDataCodewords; i++)
                {
                    resultBytes[resultOffset++] = codewordBytes[i];
                }
            }

            // Decode the contents of that stream of bytes
            return(DecodedBitStreamParser.decode(resultBytes, version, ecLevel, hints));
        }
        /// <summary> <p>When QR Codes use multiple data blocks, they are actually interleave the bytes of each of them.
        /// That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This
        /// method will separate the data into original blocks.</p>
        /// 
        /// </summary>
        /// <param name="rawCodewords">bytes as read directly from the QR Code
        /// </param>
        /// <param name="version">version of the QR Code
        /// </param>
        /// <param name="ecLevel">error-correction level of the QR Code
        /// </param>
        /// <returns> {@link DataBlock}s containing original bytes, "de-interleaved" from representation in the
        /// QR Code
        /// </returns>
        internal static DataBlock[] getDataBlocks(sbyte[] rawCodewords, Version version, ErrorCorrectionLevel ecLevel)
        {
            // Figure out the number and size of data blocks used by this version and
            // error correction level
            Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);

            // First count the total number of data blocks
            int totalBlocks = 0;
            Version.ECB[] ecBlockArray = ecBlocks.getECBlocks();
            for (int i = 0; i < ecBlockArray.Length; i++)
            {
                totalBlocks += ecBlockArray[i].getCount();
            }

            // Now establish DataBlocks of the appropriate size and number of data codewords
            DataBlock[] result = new DataBlock[totalBlocks];
            int numResultBlocks = 0;
            for (int j = 0; j < ecBlockArray.Length; j++)
            {
                Version.ECB ecBlock = ecBlockArray[j];
                for (int i = 0; i < ecBlock.getCount(); i++)
                {
                    int numDataCodewords = ecBlock.getDataCodewords();
                    int numBlockCodewords = ecBlocks.getTotalECCodewords() + numDataCodewords;
                    result[numResultBlocks++] = new DataBlock(numDataCodewords, new sbyte[numBlockCodewords]);
                }
            }

            // All blocks have the same amount of data, except that the last n
            // (where n may be 0) have 1 more byte. Figure out where these start.
            int shorterBlocksTotalCodewords = result[0].codewords.Length;
            int longerBlocksStartAt = result.Length - 1;
            while (longerBlocksStartAt >= 0)
            {
                int numCodewords = result[longerBlocksStartAt].codewords.Length;
                if (numCodewords == shorterBlocksTotalCodewords)
                {
                    break;
                }
                if (numCodewords != shorterBlocksTotalCodewords + 1)
                {
                    throw new System.SystemException("Data block sizes differ by more than 1");
                }
                longerBlocksStartAt--;
            }
            longerBlocksStartAt++;

            int shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks.getTotalECCodewords();
            // The last elements of result may be 1 element longer;
            // first fill out as many elements as all of them have
            int rawCodewordsOffset = 0;
            for (int i = 0; i < shorterBlocksNumDataCodewords; i++)
            {
                for (int j = 0; j < numResultBlocks; j++)
                {
                    result[j].codewords[i] = rawCodewords[rawCodewordsOffset++];
                }
            }
            // Fill out the last data block in the longer ones
            for (int j = longerBlocksStartAt; j < numResultBlocks; j++)
            {
                result[j].codewords[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++];
            }
            // Now add in error correction blocks
            int max = result[0].codewords.Length;
            for (int i = shorterBlocksNumDataCodewords; i < max; i++)
            {
                for (int j = 0; j < numResultBlocks; j++)
                {
                    int iOffset = j < longerBlocksStartAt ? i : i + 1;
                    result[j].codewords[iOffset] = rawCodewords[rawCodewordsOffset++];
                }
            }

            if (rawCodewordsOffset != rawCodewords.Length)
            {
                throw new System.SystemException();
            }

            return result;
        }
Beispiel #11
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()));
        }
Beispiel #12
0
 public void setECLevel(ErrorCorrectionLevel value)
 {
     ecLevel = value;
 }
 // Build 2D matrix of QR Code from "dataBits" with "ecLevel", "version" and "getMaskPattern". On
 // success, store the result in "matrix" and return true.
 public static void buildMatrix(BitVector dataBits, ErrorCorrectionLevel ecLevel, int version,int maskPattern, ByteMatrix matrix)
 {
     try{
             clearMatrix(matrix);
             embedBasicPatterns(version, matrix);
             // Type information appear with any version.
             embedTypeInfo(ecLevel, maskPattern, matrix);
             // Version info appear if version >= 7.
             maybeEmbedVersionInfo(version, matrix);
             // Data should be embedded at end.
             embedDataBits(dataBits, maskPattern, matrix);
        }catch(Exception e){
             throw  new WriterException(e.Message);
        }
 }
Beispiel #14
0
        /// <summary> <p>When QR Codes use multiple data blocks, they are actually interleaved.
        /// That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This
        /// method will separate the data into original blocks.</p>
        ///
        /// </summary>
        /// <param name="rawCodewords">bytes as read directly from the QR Code
        /// </param>
        /// <param name="version">version of the QR Code
        /// </param>
        /// <param name="ecLevel">error-correction level of the QR Code
        /// </param>
        /// <returns> {@link DataBlock}s containing original bytes, "de-interleaved" from representation in the
        /// QR Code
        /// </returns>
        internal static DataBlock[] getDataBlocks(sbyte[] rawCodewords, Version version, ErrorCorrectionLevel ecLevel)
        {
            if (rawCodewords.Length != version.TotalCodewords)
            {
                throw new System.ArgumentException();
            }

            // Figure out the number and size of data blocks used by this version and
            // error correction level
            Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);

            // First count the total number of data blocks
            int totalBlocks = 0;

            Version.ECB[] ecBlockArray = ecBlocks.getECBlocks();
            for (int i = 0; i < ecBlockArray.Length; i++)
            {
                totalBlocks += ecBlockArray[i].Count;
            }

            // Now establish DataBlocks of the appropriate size and number of data codewords
            DataBlock[] result          = new DataBlock[totalBlocks];
            int         numResultBlocks = 0;

            for (int j = 0; j < ecBlockArray.Length; j++)
            {
                Version.ECB ecBlock = ecBlockArray[j];
                for (int i = 0; i < ecBlock.Count; i++)
                {
                    int numDataCodewords  = ecBlock.DataCodewords;
                    int numBlockCodewords = ecBlocks.ECCodewordsPerBlock + numDataCodewords;
                    result[numResultBlocks++] = new DataBlock(numDataCodewords, new sbyte[numBlockCodewords]);
                }
            }

            // All blocks have the same amount of data, except that the last n
            // (where n may be 0) have 1 more byte. Figure out where these start.
            int shorterBlocksTotalCodewords = result[0].codewords.Length;
            int longerBlocksStartAt         = result.Length - 1;

            while (longerBlocksStartAt >= 0)
            {
                int numCodewords = result[longerBlocksStartAt].codewords.Length;
                if (numCodewords == shorterBlocksTotalCodewords)
                {
                    break;
                }
                longerBlocksStartAt--;
            }
            longerBlocksStartAt++;

            int shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks.ECCodewordsPerBlock;
            // The last elements of result may be 1 element longer;
            // first fill out as many elements as all of them have
            int rawCodewordsOffset = 0;

            for (int i = 0; i < shorterBlocksNumDataCodewords; i++)
            {
                for (int j = 0; j < numResultBlocks; j++)
                {
                    result[j].codewords[i] = rawCodewords[rawCodewordsOffset++];
                }
            }
            // Fill out the last data block in the longer ones
            for (int j = longerBlocksStartAt; j < numResultBlocks; j++)
            {
                result[j].codewords[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++];
            }
            // Now add in error correction blocks
            int max = result[0].codewords.Length;

            for (int i = shorterBlocksNumDataCodewords; i < max; i++)
            {
                for (int j = 0; j < numResultBlocks; j++)
                {
                    int iOffset = j < longerBlocksStartAt?i:i + 1;
                    result[j].codewords[iOffset] = rawCodewords[rawCodewordsOffset++];
                }
            }
            return(result);
        }
        // Embed type information. On success, modify the matrix.
        public static void embedTypeInfo(ErrorCorrectionLevel ecLevel, int maskPattern, ByteMatrix matrix)
        {
            BitVector typeInfoBits = new BitVector();
            makeTypeInfoBits(ecLevel, maskPattern, typeInfoBits);

            for (int i = 0; i < typeInfoBits.size(); ++i) {
              // Place bits in LSB to MSB order.  LSB (least significant bit) is the last value in
              // "typeInfoBits".
              int bit = typeInfoBits.at(typeInfoBits.size() - 1 - i);

              // Type info bits at the left top corner. See 8.9 of JISX0510:2004 (p.46).
              int x1 = TYPE_INFO_COORDINATES[i][0];
              int y1 = TYPE_INFO_COORDINATES[i][1];
              matrix.set(y1, x1, bit);

              if (i < 8) {
                // Right top corner.
                int x2 = matrix.width() - i - 1;
                int y2 = 8;
                matrix.set(y2, x2, bit);
              } else {
                // Left bottom corner.
                int x2 = 8;
                int y2 = matrix.height() - 7 + (i - 8);
                matrix.set(y2, x2, bit);
              }
            }
        }
        // Make bit vector of type information. On success, store the result in "bits" and return true.
        // Encode error correction level and mask pattern. See 8.9 of
        // JISX0510:2004 (p.45) for details.
        public static void makeTypeInfoBits(ErrorCorrectionLevel ecLevel, int maskPattern, BitVector bits)
        {
            if (!QRCode.isValidMaskPattern(maskPattern)) {
              throw new WriterException("Invalid mask pattern");
            }
            int typeInfo = (ecLevel.getBits() << 3) | maskPattern;
            bits.appendBits(typeInfo, 5);

            int bchCode = calculateBCHCode(typeInfo, TYPE_INFO_POLY);
            bits.appendBits(bchCode, 10);

            BitVector maskBits = new BitVector();
            maskBits.appendBits(TYPE_INFO_MASK_PATTERN, 15);
            bits.xor(maskBits);

            if (bits.size() != 15) {  // Just in case.
              throw new WriterException("should not happen but we got: " + bits.size());
            }
        }
Beispiel #17
0
 public ECBlocks getECBlocksForLevel(ErrorCorrectionLevel ecLevel)
 {
     return ecBlocks[ecLevel.ordinal()];
 }
        private FormatInformation(int formatInfo)
        {
            //ISO/IEC 18004:2006(E)  6.9 Format information
            //Symbol number 0:         000
            //Data mask pattern reference:       11
            //Data bits (symbol number, data mask pattern reference):  00011

            var p = SYMBOL_NUMBERS_INFO[(formatInfo >> 2) & 0x07];
            errorCorrectionLevel = p.Value;
            version = Version.getVersionForNumber(p.Key);
            dataMask = (sbyte)(formatInfo & 0x03);
        }
Beispiel #19
0
 private static int chooseMaskPattern(BitVector bits, ErrorCorrectionLevel ecLevel, int version,ByteMatrix matrix)
 {
     try{
           int minPenalty = int.MaxValue;  // Lower penalty is better.
           int bestMaskPattern = -1;
           // We try all mask patterns to choose the best one.
           for (int maskPattern = 0; maskPattern < QRCode.NUM_MASK_PATTERNS; maskPattern++)
           {
               MatrixUtil.buildMatrix(bits, ecLevel, version, maskPattern, matrix);
               int penalty = calculateMaskPenalty(matrix);
               if (penalty < minPenalty)
               {
                   minPenalty = penalty;
                   bestMaskPattern = maskPattern;
               }
           }
           return bestMaskPattern;
       }catch(Exception e){
           throw new ReaderException(e.Message);
       }
 }
Beispiel #20
0
        // Encode "bytes" with the error correction level "getECLevel". The encoding mode will be chosen
        // internally by chooseMode(). On success, store the result in "qrCode" and return true.
        // We recommend you to use QRCode.EC_LEVEL_L (the lowest level) for
        // "getECLevel" since our primary use is to show QR code on desktop screens. We don't need very
        // strong error correction for this purpose.
        //
        // Note that there is no way to encode bytes in MODE_KANJI. We might want to add EncodeWithMode()
        // with which clients can specify the encoding mode. For now, we don't need the functionality.
        public static void encode(String content, ErrorCorrectionLevel ecLevel, QRCode qrCode)
        {
            // Step 1: Choose the mode (encoding).
            Mode mode = chooseMode(content);

            // Step 2: Append "bytes" into "dataBits" in appropriate encoding.
            BitVector dataBits = new BitVector();
            appendBytes(content, mode, dataBits);
            // Step 3: Initialize QR code that can contain "dataBits".
            int numInputBytes = dataBits.sizeInBytes();
            initQRCode(numInputBytes, ecLevel, mode, qrCode);

            // Step 4: Build another bit vector that contains header and data.
            BitVector headerAndDataBits = new BitVector();
            appendModeInfo(qrCode.getMode(), headerAndDataBits);
            appendLengthInfo(content.Length, qrCode.getVersion(), qrCode.getMode(), headerAndDataBits);
            headerAndDataBits.appendBitVector(dataBits);

            // Step 5: Terminate the bits properly.
            terminateBits(qrCode.getNumDataBytes(), headerAndDataBits);

            // Step 6: Interleave data bits with error correction code.
            BitVector finalBits = new BitVector();
            interleaveWithECBytes(headerAndDataBits, qrCode.getNumTotalBytes(), qrCode.getNumDataBytes(),
                qrCode.getNumRSBlocks(), finalBits);

            // Step 7: Choose the mask pattern and set to "qrCode".
            ByteMatrix matrix = new ByteMatrix(qrCode.getMatrixWidth(), qrCode.getMatrixWidth());
            qrCode.setMaskPattern(chooseMaskPattern(finalBits, qrCode.getECLevel(), qrCode.getVersion(),
                matrix));

            // Step 8.  Build the matrix and set it to "qrCode".
            MatrixUtil.buildMatrix(finalBits, qrCode.getECLevel(), qrCode.getVersion(),
                qrCode.getMaskPattern(), matrix);
            qrCode.setMatrix(matrix);
            // Step 9.  Make sure we have a valid QR Code.
            if (!qrCode.isValid()) {
              throw new WriterException("Invalid QR code: " + qrCode.toString());
            }
        }
Beispiel #21
0
        // Initialize "qrCode" according to "numInputBytes", "ecLevel", and "mode". On success, modify
        // "qrCode".
        private static void initQRCode(int numInputBytes, ErrorCorrectionLevel ecLevel, Mode mode, QRCode qrCode)
        {
            try
              {
                qrCode.setECLevel(ecLevel);
                qrCode.setMode(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.getTotalCodewords();
                  // getNumECBytes = 130
                  Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);
                  int numEcBytes = ecBlocks.getTotalECCodewords();
                  // getNumRSBlocks = 5
                  int numRSBlocks = ecBlocks.getNumBlocks();
                  // 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!
                    qrCode.setVersion(versionNum);
                    qrCode.setNumTotalBytes(numBytes);
                    qrCode.setNumDataBytes(numDataBytes);
                    qrCode.setNumRSBlocks(numRSBlocks);
                    // getNumECBytes = 196 - 66 = 130
                    qrCode.setNumECBytes(numEcBytes);
                    // matrix width = 21 + 6 * 4 = 45
                    qrCode.setMatrixWidth(version.getDimensionForVersion());
                    return;
                  }
                }
                throw new WriterException("Cannot find proper rs block info (input data too big?)");
              }
              catch(Exception e){
                throw new WriterException(e.Message);
              }
        }
Beispiel #22
0
 public ECBlocks getECBlocksForLevel(ErrorCorrectionLevel ecLevel)
 {
     return(ecBlocks[ecLevel.ordinal()]);
 }
        public static BitVector Codeword(string content, ErrorCorrectionLevel ecLevel)
        {
			QRCodeInternal qrInternal;
			BitVector headerAndDataBits = DataEncodeUsingReferenceImplementation(content, ecLevel, out qrInternal);
			
			// Step 6: Interleave data bits with error correction code.
			BitVector finalBits = new BitVector();
			EncoderInternal.interleaveWithECBytes(headerAndDataBits, qrInternal.NumTotalBytes, qrInternal.NumDataBytes, qrInternal.NumRSBlocks, finalBits);
			
			return finalBits;
        }
        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));
        }
        //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());
        }
        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)
                    {
                        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);
        }
        /// <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);
        }