private uint SelectAndApplyMaskingPattern()
        {
            // Masks the QR code to minimize chance of data transmission error
            // See ISO/IEC 18004:2006(E), Sec. 6.8

            SymbolTemplate[] candidates = new SymbolTemplate[_dataMaskPredicates.Length - 1];
            for (int i = 0; i < candidates.Length; i++)
            {
                SymbolTemplate candidate = new SymbolTemplate(this); // copy ctor
                candidate.ApplyMask(_dataMaskPredicates[i]);
                candidates[i] = candidate;
            }

            int lowestPenaltyScoreValue = candidates[0].CalculatePenaltyScore();
            int lowestPenaltyScoreIndex = 0;

            for (int i = 1; i < candidates.Length; i++)
            {
                int candidatePenaltyScoreValue = candidates[i].CalculatePenaltyScore();
                if (candidatePenaltyScoreValue < lowestPenaltyScoreValue)
                {
                    lowestPenaltyScoreValue = candidatePenaltyScoreValue;
                    lowestPenaltyScoreIndex = i;
                }
            }

            // copy the candidate modules array into me; copy by ref is fine
            this._modules = candidates[lowestPenaltyScoreIndex]._modules;
            return((uint)lowestPenaltyScoreIndex);
        }
        internal static IEnumerable<Coord> GetBitStreamMapping(SymbolTemplate symbol)
        {
            // See ISO/IEC 18004:2006(E), Sec. 6.7.3 for information on where codewords
            // are placed in the matrix.

            int width = symbol.Width;

            bool isMovingUpward = true;
            for (int col = width - 1; col > 0; col -= 2)
            {
                // Column six is used as a timing pattern and is skipped for codeword placement
                if (col == 6) { col--; }

                if (isMovingUpward)
                {
                    for (int row = width - 1; row >= 0; row--)
                    {
                        if (!symbol.IsReservedModule(row, col)) { yield return new Coord(row, col); }
                        if (!symbol.IsReservedModule(row, col - 1)) { yield return new Coord(row, col - 1); }
                    }
                }
                else
                {
                    for (int row = 0; row < width; row++)
                    {
                        if (!symbol.IsReservedModule(row, col)) { yield return new Coord(row, col); }
                        if (!symbol.IsReservedModule(row, col - 1)) { yield return new Coord(row, col - 1); }
                    }
                }

                isMovingUpward = !isMovingUpward; // reverse direction when hitting the end of the matrix
            }
        }
 // copy ctor
 private SymbolTemplate(SymbolTemplate prototype)
 {
     this._modules             = prototype._modules.CreateCopy();
     this.ErrorCorrectionLevel = prototype.ErrorCorrectionLevel;
     this.Version = prototype.Version;
     this.Width   = prototype.Width;
 }
 // copy ctor
 private SymbolTemplate(SymbolTemplate prototype)
 {
     this._modules = prototype._modules.CreateCopy();
     this.ErrorCorrectionLevel = prototype.ErrorCorrectionLevel;
     this.Version = prototype.Version;
     this.Width = prototype.Width;
 }
        internal static IEnumerable <Coord> GetBitStreamMapping(SymbolTemplate symbol)
        {
            // See ISO/IEC 18004:2006(E), Sec. 6.7.3 for information on where codewords
            // are placed in the matrix.

            int width = symbol.Width;

            bool isMovingUpward = true;

            for (int col = width - 1; col > 0; col -= 2)
            {
                // Column six is used as a timing pattern and is skipped for codeword placement
                if (col == 6)
                {
                    col--;
                }

                if (isMovingUpward)
                {
                    for (int row = width - 1; row >= 0; row--)
                    {
                        if (!symbol.IsReservedModule(row, col))
                        {
                            yield return(new Coord(row, col));
                        }
                        if (!symbol.IsReservedModule(row, col - 1))
                        {
                            yield return(new Coord(row, col - 1));
                        }
                    }
                }
                else
                {
                    for (int row = 0; row < width; row++)
                    {
                        if (!symbol.IsReservedModule(row, col))
                        {
                            yield return(new Coord(row, col));
                        }
                        if (!symbol.IsReservedModule(row, col - 1))
                        {
                            yield return(new Coord(row, col - 1));
                        }
                    }
                }

                isMovingUpward = !isMovingUpward; // reverse direction when hitting the end of the matrix
            }
        }
        public static SymbolTemplate CreateTemplate(int version)
        {
            Debug.Assert(1 <= version && version <= 40);

            // Lazy initialization of this symbol template
            SymbolTemplate template = Volatile.Read(ref _symbolTemplates[version - 1]);

            if (template == null)
            {
                SymbolTemplate newTemplate = new SymbolTemplate(version);
                template = Interlocked.CompareExchange(ref _symbolTemplates[version - 1], newTemplate, null) ?? newTemplate;
            }

            // Return a copy since the templates are mutable
            return(new SymbolTemplate(template));
        }
예제 #7
0
        public static Image GetQRCode(byte[] data, ErrorCorrectionLevel level = ErrorCorrectionLevel.M)
        {
            bool requires16BitLength    = false;
            int  maxBytesInVersion9Code = QRErrorCorrections.GetQRVersionInfo(9).GetCorrectionInfo(level).TotalDataBytes;

            if (maxBytesInVersion9Code - 2 < data.Length)
            {
                // This data requires a version 10 or higher code; will not fit in version 9 or lower.
                // Version 10 and higher codes require 16-bit data lengths.
                requires16BitLength = true;
            }

            StreamHelper sh = new StreamHelper();

            sh.WriteNibble(0x04); // byte mode
            if (requires16BitLength)
            {
                sh.WriteWord((ushort)data.Length);
            }
            else
            {
                sh.WriteByte((byte)data.Length);
            }
            sh.WriteBytes(new ArraySegment <byte>(data));
            sh.WriteNibble(0x00); // terminator
            byte[] binaryData = sh.ToArray();

            int qrCodeVersion;
            ErrorCorrectionLevel errorCorrectionLevel;

            byte[] finalMessageSequence = QRErrorCorrections.GetMessageSequence(binaryData, level, out qrCodeVersion, out errorCorrectionLevel);

            SymbolTemplate template = SymbolTemplate.CreateTemplate(qrCodeVersion);

            template.ErrorCorrectionLevel = errorCorrectionLevel;
            template.PopulateData(finalMessageSequence);
            template.Complete();

            return(template.ToImage());
        }
 internal static IEnumerable<CodewordPlacement> GetCodewordPlacements(SymbolTemplate symbol)
 {
     var bitstreamMapping = GetBitStreamMapping(symbol);
     return GetCodewordPlacementsImpl(bitstreamMapping);
 }
        internal static IEnumerable <CodewordPlacement> GetCodewordPlacements(SymbolTemplate symbol)
        {
            var bitstreamMapping = GetBitStreamMapping(symbol);

            return(GetCodewordPlacementsImpl(bitstreamMapping));
        }
        private uint SelectAndApplyMaskingPattern()
        {
            // Masks the QR code to minimize chance of data transmission error
            // See ISO/IEC 18004:2006(E), Sec. 6.8

            SymbolTemplate[] candidates = new SymbolTemplate[_dataMaskPredicates.Length - 1];
            for (int i = 0; i < candidates.Length; i++)
            {
                SymbolTemplate candidate = new SymbolTemplate(this); // copy ctor
                candidate.ApplyMask(_dataMaskPredicates[i]);
                candidates[i] = candidate;
            }

            int lowestPenaltyScoreValue = candidates[0].CalculatePenaltyScore();
            int lowestPenaltyScoreIndex = 0;
            for (int i = 1; i < candidates.Length; i++)
            {
                int candidatePenaltyScoreValue = candidates[i].CalculatePenaltyScore();
                if (candidatePenaltyScoreValue < lowestPenaltyScoreValue)
                {
                    lowestPenaltyScoreValue = candidatePenaltyScoreValue;
                    lowestPenaltyScoreIndex = i;
                }
            }

            // copy the candidate modules array into me; copy by ref is fine
            this._modules = candidates[lowestPenaltyScoreIndex]._modules;
            return (uint)lowestPenaltyScoreIndex;
        }
        public static SymbolTemplate CreateTemplate(int version)
        {
            Debug.Assert(1 <= version && version <= 40);

            // Lazy initialization of this symbol template
            SymbolTemplate template = Volatile.Read(ref _symbolTemplates[version - 1]);
            if (template == null)
            {
                SymbolTemplate newTemplate = new SymbolTemplate(version);
                template = Interlocked.CompareExchange(ref _symbolTemplates[version - 1], newTemplate, null) ?? newTemplate;
            }

            // Return a copy since the templates are mutable
            return new SymbolTemplate(template);
        }