Beispiel #1
0
        public static Bitmap GetImage(EncodeProperties properties, out int QRCodeVersion, MaskPatterns maskPattern = MaskPatterns.Pattern0)
        {
            if (properties == null)
            {
                throw new NullReferenceException("empty properties");
            }

            // ReSharper disable once InconsistentNaming
            Bitmap QRCodeBitmap = new Bitmap(properties.Size, properties.Size);

            int maxLength;
            int version;

            bool[] modeSequence;

            bool[] InputData;
            int    RequestedCapacity;

            bool[] Terminator;
            bool[] Additoin0s;

            bool[] FullData;
            bool[] CharacterCountIndicator;
            int    CharacterCountIndicatorLength;

            CharacterCapacities.GetMaxCapacityAndVersion(properties.Text, properties.ErrorCorrectionLvl, properties.Mode, out version, out maxLength);
            CharacterCountIndicatorLength = CharacterCapacities.GetCharacterCountIndicatorLength(version, properties.Mode);
            switch (properties.Mode)
            {
            case EncodeMode.Numeric:
                InputData    = Encode.Numeric(properties.Text);
                modeSequence = new[] { false, false, false, true };
                break;

            case EncodeMode.Alphanumeric:
                InputData    = Encode.Alphanumeric(properties.Text);
                modeSequence = new[] { false, false, true, false };
                break;

            default:
                throw new NotImplementedException();
                break;
            }
            CharacterCountIndicator = GetCharacterCountIndicator(properties.Text, CharacterCountIndicatorLength);

            #region fill Data to Max Capacity (Terminator)

            RequestedCapacity = ErrorCorrectionTable.getTotalDataCodeBits((int)properties.ErrorCorrectionLvl, version);

            int missingSymbCount = RequestedCapacity - InputData.Length - CharacterCountIndicatorLength - modeSequence.Length;

            if (missingSymbCount > 4)
            {
                Terminator    = new bool[4];
                Terminator[0] = false;
                Terminator[1] = false;
                Terminator[2] = false;
                Terminator[3] = false;
                int adding = 8 - (InputData.Length + CharacterCountIndicatorLength + modeSequence.Length + Terminator.Length) % 8;
                if (adding == 8)
                {
                    adding = 0;
                }
                Additoin0s = new bool[adding];
                for (int i = 0; i < adding; i++)
                {
                    Additoin0s[i] = false;
                }
                Helper.joinArrs <bool> (ref Terminator, Additoin0s);
                bool[] Pad1 = { true, true, true, false, true, true, false, false };
                bool[] Pad2 = { false, false, false, true, false, false, false, true };
                missingSymbCount = RequestedCapacity - InputData.Length - CharacterCountIndicatorLength - modeSequence.Length - Terminator.Length;
                while (missingSymbCount > 0)
                {
                    Helper.joinArrs <bool> (ref Terminator, Pad1);
                    missingSymbCount = RequestedCapacity - InputData.Length - CharacterCountIndicatorLength - modeSequence.Length - Terminator.Length;
                    if (missingSymbCount > 0)
                    {
                        Helper.joinArrs <bool> (ref Terminator, Pad2);
                    }
                    else
                    {
                        break;
                    }
                    missingSymbCount = RequestedCapacity - InputData.Length - CharacterCountIndicatorLength - modeSequence.Length - Terminator.Length;
                }
            }
            else
            {
                Terminator = new bool[missingSymbCount];
                Additoin0s = new bool[0];
                for (int i = 0; i < missingSymbCount; i++)
                {
                    Terminator[i] = false;
                }
            }
            #endregion

            FullData = modeSequence;
            Helper.joinArrs <bool>(ref FullData, CharacterCountIndicator);
            Helper.joinArrs <bool> (ref FullData, InputData);
            Helper.joinArrs <bool> (ref FullData, Terminator);


            #region BLOCKING and polynomial devisions
            int numOfBlocksInGroup1            = ErrorCorrectionTable.GetNumOfBlocksInGroup1(properties.ErrorCorrectionLvl, version);
            int numOfBlocksInGroup2            = ErrorCorrectionTable.GetNumOfBlocksInGroup2(properties.ErrorCorrectionLvl, version);
            int numOfCodeWordsInBlocksInGroup1 = ErrorCorrectionTable.GetNumOfCodeWordsInBlocksInGroup1(properties.ErrorCorrectionLvl, version);
            int numOfCodeWordsInBlocksInGroup2 = ErrorCorrectionTable.GetNumOfCodeWordsInBlocksInGroup2(properties.ErrorCorrectionLvl, version);
            int numOfECCodewordsPerBlock       = ErrorCorrectionTable.GetErrorCorrectionCodewordsPerBlock(properties.ErrorCorrectionLvl, version);

            int iteratorFullData = 0;
            BlockOfCodeWords[] groupOfDataCodewords1 = null;
            BlockOfCodeWords[] groupOfDataCodewords2 = null;
            BlockOfCodeWords[] groupOfECCodewords1   = null;
            BlockOfCodeWords[] groupOfECCodewords2   = null;

            int[] FullDataInts = Encode.UnBinary(FullData, 8);


            if (numOfBlocksInGroup1 > 0)
            {
                groupOfDataCodewords1 = new BlockOfCodeWords[numOfBlocksInGroup1];
                groupOfECCodewords1   = new BlockOfCodeWords[numOfBlocksInGroup1];
                for (int i = 0; i < numOfBlocksInGroup1; i++)
                {
                    groupOfDataCodewords1[i]           = new BlockOfCodeWords();
                    groupOfDataCodewords1[i].CodeWords = new int[numOfCodeWordsInBlocksInGroup1];
                    for (int j = 0; j < numOfCodeWordsInBlocksInGroup1; j++)
                    {
                        groupOfDataCodewords1[i].CodeWords[j] = FullDataInts[iteratorFullData];
                        iteratorFullData++;
                    }
                    groupOfECCodewords1[i]           = new BlockOfCodeWords();
                    groupOfECCodewords1[i].CodeWords = PolynomialDevision(properties.ErrorCorrectionLvl, version,
                                                                          groupOfDataCodewords1[i].CodeWords);
                }
            }
            if (numOfBlocksInGroup2 > 0)
            {
                groupOfDataCodewords2 = new BlockOfCodeWords[numOfBlocksInGroup2];
                groupOfECCodewords2   = new BlockOfCodeWords[numOfBlocksInGroup2];
                for (int i = 0; i < numOfBlocksInGroup2; i++)
                {
                    groupOfDataCodewords2[i]           = new BlockOfCodeWords();
                    groupOfDataCodewords2[i].CodeWords = new int[numOfCodeWordsInBlocksInGroup2];
                    for (int j = 0; j < numOfCodeWordsInBlocksInGroup2; j++)
                    {
                        groupOfDataCodewords2[i].CodeWords[j] = FullDataInts[iteratorFullData];
                        iteratorFullData++;
                    }
                    groupOfECCodewords2[i]           = new BlockOfCodeWords();
                    groupOfECCodewords2[i].CodeWords = PolynomialDevision(properties.ErrorCorrectionLvl, version,
                                                                          groupOfDataCodewords2[i].CodeWords);
                }
            }
            int[] FullMessageData = new int[FullDataInts.Length];
            int[] FullMessageEC   =
                new int[
                    groupOfDataCodewords2 == null
                                            ? numOfBlocksInGroup1 * numOfECCodewordsPerBlock
                                            : (numOfBlocksInGroup1 + numOfBlocksInGroup2) * numOfECCodewordsPerBlock];

            int iteratorFullMessageData = 0;
            int iteratorFullMessageEC   = 0;
            int forMam = numOfCodeWordsInBlocksInGroup2 > 0 ? numOfCodeWordsInBlocksInGroup2 : numOfCodeWordsInBlocksInGroup1;
            for (int i = 0; i < forMam; i++)
            {
                if (groupOfDataCodewords1 != null && numOfCodeWordsInBlocksInGroup1 > i)
                {
                    for (int j = 0; j < numOfBlocksInGroup1; j++)
                    {
                        FullMessageData[iteratorFullMessageData] = groupOfDataCodewords1[j].CodeWords[i];
                        iteratorFullMessageData++;
                    }
                }
                if (groupOfDataCodewords2 != null)
                {
                    for (int j = 0; j < numOfBlocksInGroup2; j++)
                    {
                        FullMessageData[iteratorFullMessageData] = groupOfDataCodewords2[j].CodeWords[i];
                        iteratorFullMessageData++;
                    }
                }
            }
            for (int i = 0; i < numOfECCodewordsPerBlock; i++)
            {
                if (groupOfECCodewords1 != null)
                {
                    for (int j = 0; j < numOfBlocksInGroup1; j++)
                    {
                        FullMessageEC[iteratorFullMessageEC] = groupOfECCodewords1[j].CodeWords[i];
                        iteratorFullMessageEC++;
                    }
                }
                if (groupOfECCodewords2 != null)
                {
                    for (int j = 0; j < numOfBlocksInGroup2; j++)
                    {
                        FullMessageEC[iteratorFullMessageEC] = groupOfECCodewords2[j].CodeWords[i];
                        iteratorFullMessageEC++;
                    }
                }
            }
            var LastFullMessageInts  = Helper.joinArrs(FullMessageData, FullMessageEC);
            var LastFullMessageBools = new bool[0];
            for (int i = 0; i < LastFullMessageInts.Length; i++)
            {
                Helper.joinArrs <bool> (ref LastFullMessageBools, Encode.Binary(LastFullMessageInts[i]));
            }
            #endregion



            //var XORresult = PolynomialDevision ( properties.ErrorCorrectionLvl , version , FullDataInts );
            //var ErrCorrKeyWord = new bool[0];
            //for ( int i = 0 ; i < XORresult.Length ; i++ ) {
            //	Helper.joinArrs<bool> ( ref ErrCorrKeyWord , Encode.Binary ( XORresult[i] ) );
            //}
            QRCodeVersion = version;
            return(Generate(version, CharacterCountIndicator, InputData, Terminator, modeSequence, LastFullMessageBools, 5, properties.ErrorCorrectionLvl, maskPattern));
        }