Example #1
0
        public static int MaskCode(ref QrCode qrCode, int version, ref List <Rectangle> blockedModules)
        {
            var patternName  = String.Empty;
            var patternScore = 0;

            var size = qrCode.ModuleMatrix.Count;

            foreach (var pattern in typeof(MaskPattern).GetMethods())
            {
                if (pattern.Name.Length == 8 && pattern.Name.Substring(0, 7) == "Pattern")
                {
                    var qrTemp = new QrCode(version);
                    for (var y = 0; y < size; y++)
                    {
                        for (var x = 0; x < size; x++)
                        {
                            qrTemp.ModuleMatrix[y][x] = qrCode.ModuleMatrix[y][x];
                        }
                    }


                    for (var x = 0; x < size; x++)
                    {
                        for (var y = 0; y < size; y++)
                        {
                            if (!IsBlocked(new Rectangle(x, y, 1, 1), blockedModules))
                            {
                                qrTemp.ModuleMatrix[y][x] ^= (bool)pattern.Invoke(null, new object[] { x, y });
                            }
                        }
                    }

                    var score = MaskPattern.Score(ref qrTemp);
                    if (String.IsNullOrEmpty(patternName) || patternScore > score)
                    {
                        patternName  = pattern.Name;
                        patternScore = score;
                    }
                }
            }
            var patterMethod = typeof(MaskPattern).GetMethods().Where(x => x.Name == patternName).First();

            for (var x = 0; x < size; x++)
            {
                for (var y = 0; y < size; y++)
                {
                    if (!IsBlocked(new Rectangle(x, y, 1, 1), blockedModules))
                    {
                        qrCode.ModuleMatrix[y][x] ^= (bool)patterMethod.Invoke(null, new object[] { x, y });
                    }
                }
            }
            return(Convert.ToInt32(patterMethod.Name.Substring(patterMethod.Name.Length - 1, 1)) - 1);
        }
Example #2
0
        public static void PlaceTimingPatterns(ref QrCode qrCode, ref List <Rectangle> blockedModules)
        {
            var size = qrCode.ModuleMatrix.Count;

            for (var i = 8; i < size - 8; i++)
            {
                if (i % 2 == 0)
                {
                    qrCode.ModuleMatrix[6][i] = true;
                    qrCode.ModuleMatrix[i][6] = true;
                }
            }
            blockedModules.AddRange(new[] { new Rectangle(6, 8, 1, size - 16), new Rectangle(8, 6, size - 16, 1) });
        }
Example #3
0
        public static void PlaceVersion(ref QrCode qrCode, string versionStr)
        {
            var size = qrCode.ModuleMatrix.Count;
            var vStr = new string(versionStr.Reverse().ToArray());

            for (var x = 0; x < 6; x++)
            {
                for (var y = 0; y < 3; y++)
                {
                    qrCode.ModuleMatrix[y + size - 11][x] = vStr[x * 3 + y] == '1' ? true : false;
                    qrCode.ModuleMatrix[x][y + size - 11] = vStr[x * 3 + y] == '1' ? true : false;
                }
            }
        }
Example #4
0
        public static void PlaceFormat(ref QrCode qrCode, string formatStr)
        {
            var size    = qrCode.ModuleMatrix.Count;
            var fStr    = new string(formatStr.Reverse().ToArray());
            var modules = new int[15, 4] {
                { 8, 0, size - 1, 8 }, { 8, 1, size - 2, 8 }, { 8, 2, size - 3, 8 }, { 8, 3, size - 4, 8 }, { 8, 4, size - 5, 8 }, { 8, 5, size - 6, 8 }, { 8, 7, size - 7, 8 }, { 8, 8, size - 8, 8 }, { 7, 8, 8, size - 7 }, { 5, 8, 8, size - 6 }, { 4, 8, 8, size - 5 }, { 3, 8, 8, size - 4 }, { 2, 8, 8, size - 3 }, { 1, 8, 8, size - 2 }, { 0, 8, 8, size - 1 }
            };

            for (var i = 0; i < 15; i++)
            {
                var p1 = new Point(modules[i, 0], modules[i, 1]);
                var p2 = new Point(modules[i, 2], modules[i, 3]);
                qrCode.ModuleMatrix[p1.Y][p1.X] = fStr[i] == '1' ? true : false;
                qrCode.ModuleMatrix[p2.Y][p2.X] = fStr[i] == '1' ? true : false;
            }
        }
Example #5
0
        public static void PlaceDataWords(ref QrCode qrCode, string data, ref List <Rectangle> blockedModules)
        {
            var size      = qrCode.ModuleMatrix.Count;
            var up        = true;
            var datawords = new Queue <bool>();

            data.ToList().ForEach(x => datawords.Enqueue(x == '0' ? false : true));
            for (var x = size - 1; x >= 0; x = x - 2)
            {
                if (x == 7 || x == 6)
                {
                    x = 5;
                }
                for (var yMod = 1; yMod <= size; yMod++)
                {
                    var y = 0;
                    if (up)
                    {
                        y = size - yMod;
                        if (datawords.Count > 0 && !IsBlocked(new Rectangle(x, y, 1, 1), blockedModules))
                        {
                            qrCode.ModuleMatrix[y][x] = datawords.Dequeue();
                        }
                        if (datawords.Count > 0 && x > 0 && !IsBlocked(new Rectangle(x - 1, y, 1, 1), blockedModules))
                        {
                            qrCode.ModuleMatrix[y][x - 1] = datawords.Dequeue();
                        }
                    }
                    else
                    {
                        y = yMod - 1;
                        if (datawords.Count > 0 && !IsBlocked(new Rectangle(x, y, 1, 1), blockedModules))
                        {
                            qrCode.ModuleMatrix[y][x] = datawords.Dequeue();
                        }
                        if (datawords.Count > 0 && x > 0 && !IsBlocked(new Rectangle(x - 1, y, 1, 1), blockedModules))
                        {
                            qrCode.ModuleMatrix[y][x - 1] = datawords.Dequeue();
                        }
                    }
                }
                up = !up;
            }
        }
Example #6
0
        public static void PlaceFinderPatterns(ref QrCode qrCode, ref List <Rectangle> blockedModules)
        {
            var size = qrCode.ModuleMatrix.Count;

            int[] locations = { 0, 0, size - 7, 0, 0, size - 7 };

            for (var i = 0; i < 6; i = i + 2)
            {
                for (var x = 0; x < 7; x++)
                {
                    for (var y = 0; y < 7; y++)
                    {
                        if (!(((x == 1 || x == 5) && y > 0 && y < 6) || (x > 0 && x < 6 && (y == 1 || y == 5))))
                        {
                            qrCode.ModuleMatrix[y + locations[i + 1]][x + locations[i]] = true;
                        }
                    }
                }
                blockedModules.Add(new Rectangle(locations[i], locations[i + 1], 7, 7));
            }
        }
Example #7
0
 public static void PlaceDarkModule(ref QrCode qrCode, int version, ref List <Rectangle> blockedModules)
 {
     qrCode.ModuleMatrix[4 * version + 9][8] = true;
     blockedModules.Add(new Rectangle(8, 4 * version + 9, 1, 1));
 }
Example #8
0
        public static int Score(ref QrCode qrCode)
        {
            var score = 0;
            var size  = qrCode.ModuleMatrix.Count;

            //Penalty 1
            for (int y = 0; y < size; y++)
            {
                var modInRow      = 0;
                var modInColumn   = 0;
                var lastValRow    = qrCode.ModuleMatrix[y][0];
                var lastValColumn = qrCode.ModuleMatrix[0][y];
                for (int x = 0; x < size; x++)
                {
                    if (qrCode.ModuleMatrix[y][x] == lastValRow)
                    {
                        modInRow++;
                    }
                    else
                    {
                        modInRow = 1;
                    }
                    if (modInRow == 5)
                    {
                        score += 3;
                    }
                    else if (modInRow > 5)
                    {
                        score++;
                    }
                    lastValRow = qrCode.ModuleMatrix[y][x];


                    if (qrCode.ModuleMatrix[x][y] == lastValColumn)
                    {
                        modInColumn++;
                    }
                    else
                    {
                        modInColumn = 1;
                    }
                    if (modInColumn == 5)
                    {
                        score += 3;
                    }
                    else if (modInColumn > 5)
                    {
                        score++;
                    }
                    lastValColumn = qrCode.ModuleMatrix[x][y];
                }
            }


            //Penalty 2
            for (int y = 0; y < size - 1; y++)
            {
                for (int x = 0; x < size - 1; x++)
                {
                    if (qrCode.ModuleMatrix[y][x] == qrCode.ModuleMatrix[y][x + 1] &&
                        qrCode.ModuleMatrix[y][x] == qrCode.ModuleMatrix[y + 1][x] &&
                        qrCode.ModuleMatrix[y][x] == qrCode.ModuleMatrix[y + 1][x + 1])
                    {
                        score += 3;
                    }
                }
            }

            //Penalty 3
            for (int y = 0; y < size; y++)
            {
                for (int x = 0; x < size - 10; x++)
                {
                    if ((qrCode.ModuleMatrix[y][x] &&
                         !qrCode.ModuleMatrix[y][x + 1] &&
                         qrCode.ModuleMatrix[y][x + 2] &&
                         qrCode.ModuleMatrix[y][x + 3] &&
                         qrCode.ModuleMatrix[y][x + 4] &&
                         !qrCode.ModuleMatrix[y][x + 5] &&
                         qrCode.ModuleMatrix[y][x + 6] &&
                         !qrCode.ModuleMatrix[y][x + 7] &&
                         !qrCode.ModuleMatrix[y][x + 8] &&
                         !qrCode.ModuleMatrix[y][x + 9] &&
                         !qrCode.ModuleMatrix[y][x + 10]) ||
                        (!qrCode.ModuleMatrix[y][x] &&
                         !qrCode.ModuleMatrix[y][x + 1] &&
                         !qrCode.ModuleMatrix[y][x + 2] &&
                         !qrCode.ModuleMatrix[y][x + 3] &&
                         qrCode.ModuleMatrix[y][x + 4] &&
                         !qrCode.ModuleMatrix[y][x + 5] &&
                         qrCode.ModuleMatrix[y][x + 6] &&
                         qrCode.ModuleMatrix[y][x + 7] &&
                         qrCode.ModuleMatrix[y][x + 8] &&
                         !qrCode.ModuleMatrix[y][x + 9] &&
                         qrCode.ModuleMatrix[y][x + 10]))
                    {
                        score += 40;
                    }

                    if ((qrCode.ModuleMatrix[x][y] &&
                         !qrCode.ModuleMatrix[x + 1][y] &&
                         qrCode.ModuleMatrix[x + 2][y] &&
                         qrCode.ModuleMatrix[x + 3][y] &&
                         qrCode.ModuleMatrix[x + 4][y] &&
                         !qrCode.ModuleMatrix[x + 5][y] &&
                         qrCode.ModuleMatrix[x + 6][y] &&
                         !qrCode.ModuleMatrix[x + 7][y] &&
                         !qrCode.ModuleMatrix[x + 8][y] &&
                         !qrCode.ModuleMatrix[x + 9][y] &&
                         !qrCode.ModuleMatrix[x + 10][y]) ||
                        (!qrCode.ModuleMatrix[x][x] &&
                         !qrCode.ModuleMatrix[x + 1][y] &&
                         !qrCode.ModuleMatrix[x + 2][y] &&
                         !qrCode.ModuleMatrix[x + 3][y] &&
                         qrCode.ModuleMatrix[x + 4][y] &&
                         !qrCode.ModuleMatrix[x + 5][y] &&
                         qrCode.ModuleMatrix[x + 6][y] &&
                         qrCode.ModuleMatrix[x + 7][y] &&
                         qrCode.ModuleMatrix[x + 8][y] &&
                         !qrCode.ModuleMatrix[x + 9][y] &&
                         qrCode.ModuleMatrix[x + 10][y]))
                    {
                        score += 40;
                    }
                }
            }

            //Penalty 4
            var blackModules = 0;

            foreach (var row in qrCode.ModuleMatrix)
            {
                foreach (bool bit in row)
                {
                    if (bit)
                    {
                        blackModules++;
                    }
                }
            }

            var percent = (blackModules / (qrCode.ModuleMatrix.Count * qrCode.ModuleMatrix.Count)) * 100;

            if (percent % 5 == 0)
            {
                score += Math.Min((Math.Abs(percent - 55) / 5), (Math.Abs(percent - 45) / 5)) * 10;
            }
            else
            {
                score += Math.Min((Math.Abs((int)Math.Floor((decimal)percent / 5) - 50) / 5), (Math.Abs(((int)Math.Floor((decimal)percent / 5) + 5) - 50) / 5)) * 10;
            }

            return(score);
        }
Example #9
0
        public QrCode CreateQrCode(string plainText, ECCLevel eccLevel, bool utf8Bom = false)
        {
            var encoding        = GetEncodingFromPlaintext(plainText);
            var codedText       = PlainTextToBinary(plainText, encoding, utf8Bom);
            var dataInputLength = GetDataLength(encoding, plainText, codedText);
            var version         = GetVersion(dataInputLength, encoding, eccLevel);

            var modeIndicator  = DecToBin((int)encoding, 4);
            var countIndicator = DecToBin(dataInputLength, GetCountIndicatorLength(version, encoding));
            var bitString      = modeIndicator + countIndicator;


            bitString += codedText;

            //Fill up data code word
            var eccInfo    = _capacityEccTable.Where(x => x.Version == version && x.ErrorCorrectionLevel.Equals(eccLevel)).Single();
            var dataLength = eccInfo.TotalDataCodewords * 8;
            var lengthDiff = dataLength - bitString.Length;

            if (lengthDiff > 0)
            {
                bitString += new string('0', Math.Min(lengthDiff, 4));
            }
            if ((bitString.Length % 8) != 0)
            {
                bitString += new string('0', 8 - (bitString.Length % 8));
            }
            while (bitString.Length < dataLength)
            {
                bitString += "1110110000010001";
            }
            if (bitString.Length > dataLength)
            {
                bitString = bitString.Substring(0, dataLength);
            }

            //Calculate error correction words
            var codeWordWithEcc = new List <CodewordBlock>();

            for (var i = 0; i < eccInfo.BlocksInGroup1; i++)
            {
                var bitStr = bitString.Substring(i * eccInfo.CodewordsInGroup1 * 8, eccInfo.CodewordsInGroup1 * 8);
                codeWordWithEcc.Add(new CodewordBlock {
                    BitString = bitStr, BlockNumber = i + 1, GroupNumber = 1, CodeWords = BinaryStringToBitBlockList(bitStr), ECCWords = CalculateEccWords(bitStr, eccInfo)
                });
            }
            bitString = bitString.Substring(eccInfo.BlocksInGroup1 * eccInfo.CodewordsInGroup1 * 8);
            for (var i = 0; i < eccInfo.BlocksInGroup2; i++)
            {
                var bitStr = bitString.Substring(i * eccInfo.CodewordsInGroup2 * 8, eccInfo.CodewordsInGroup2 * 8);
                codeWordWithEcc.Add(new CodewordBlock {
                    BitString = bitStr, BlockNumber = i + 1, GroupNumber = 2, CodeWords = BinaryStringToBitBlockList(bitStr), ECCWords = CalculateEccWords(bitStr, eccInfo)
                });
            }


            //Interleave code words
            var interleavedWordsSb = new StringBuilder();

            for (var i = 0; i < Math.Max(eccInfo.CodewordsInGroup1, eccInfo.CodewordsInGroup2); i++)
            {
                foreach (var codeBlock in codeWordWithEcc)
                {
                    if (codeBlock.CodeWords.Count > i)
                    {
                        interleavedWordsSb.Append(codeBlock.CodeWords[i]);
                    }
                }
            }


            for (var i = 0; i < eccInfo.ECCPerBlock; i++)
            {
                foreach (var codeBlock in codeWordWithEcc)
                {
                    if (codeBlock.ECCWords.Count > i)
                    {
                        interleavedWordsSb.Append(codeBlock.ECCWords[i]);
                    }
                }
            }
            interleavedWordsSb.Append(new string('0', _remainderBits[version - 1]));
            var interleavedData = interleavedWordsSb.ToString();


            //Place interleaved data on module matrix
            var qr             = new QrCode(version);
            var blockedModules = new List <Rectangle>();

            ModulePlacer.PlaceFinderPatterns(ref qr, ref blockedModules);
            ModulePlacer.ReserveSeperatorAreas(qr.ModuleMatrix.Count, ref blockedModules);
            ModulePlacer.PlaceAlignmentPatterns(ref qr, _alignmentPatternTable.Where(x => x.Version == version).Select(x => x.PatternPositions).First(), ref blockedModules);
            ModulePlacer.PlaceTimingPatterns(ref qr, ref blockedModules);
            ModulePlacer.PlaceDarkModule(ref qr, version, ref blockedModules);
            ModulePlacer.ReserveVersionAreas(qr.ModuleMatrix.Count, version, ref blockedModules);
            ModulePlacer.PlaceDataWords(ref qr, interleavedData, ref blockedModules);
            var maskVersion = ModulePlacer.MaskCode(ref qr, version, ref blockedModules);
            var formatStr   = GetFormatString(eccLevel, maskVersion);

            ModulePlacer.PlaceFormat(ref qr, formatStr);
            if (version >= 7)
            {
                var versionString = GetVersionString(version);
                ModulePlacer.PlaceVersion(ref qr, versionString);
            }
            ModulePlacer.AddQuietZone(ref qr);
            return(qr);
        }