Beispiel #1
0
        public static QRCode EncodeText(string text, CorrectionLevel correctionLevel)
        {
            if (text is null)
            {
                throw new ArgumentNullException(nameof(text));
            }

            if (correctionLevel is null)
            {
                throw new ArgumentNullException(nameof(correctionLevel));
            }

            return(EncodeSegments(QRSegment.CreateSegments(text), correctionLevel));
        }
Beispiel #2
0
        public static QRCode EncodeBytes(byte[] data, CorrectionLevel correctionLevel)
        {
            if (data is null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (correctionLevel is null)
            {
                throw new ArgumentNullException(nameof(correctionLevel));
            }

            return(EncodeSegments(new[] { QRSegment.CreateByteSegment(data) }, correctionLevel));
        }
Beispiel #3
0
        public static QRCode EncodeSegments(IEnumerable <QRSegment> segments, CorrectionLevel correctionLevel, int minVersion, int maxVersion, Mask mask, bool boostECL)
        {
            if (segments is null)
            {
                throw new ArgumentNullException(nameof(segments));
            }

            if (correctionLevel is null)
            {
                throw new ArgumentNullException(nameof(correctionLevel));
            }

            if (!(MinVersion <= minVersion && minVersion <= maxVersion && maxVersion <= MaxVersion))
            {
                throw new ArgumentOutOfRangeException(nameof(minVersion), nameof(maxVersion));
            }

            List <QRSegment> segmentList = segments.ToList();

            int version;
            int usedBits;

            for (version = minVersion; ; ++version)
            {
                int capacity = ComputeCodewordsCount(version, correctionLevel) * 8;
                usedBits = QRSegment.ComputeBitLength(segmentList, version);
                if (usedBits != -1 && usedBits <= capacity)
                {
                    break;
                }

                if (version >= maxVersion)
                {
                    throw new ArgumentOutOfRangeException(nameof(segments), "Data length was too long");
                }
            }

            if (boostECL)
            {
                while (correctionLevel.Id != CorrectionLevel.MaxValue)
                {
                    CorrectionLevel check = correctionLevel + 1;
                    if (usedBits <= ComputeCodewordsCount(version, check) * 8)
                    {
                        correctionLevel = check;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            BitList bits = new BitList();

            foreach (QRSegment segment in segmentList)
            {
                bits.Add(segment.Mode.ModeBits, 4);
                bits.Add(segment.CharsCount, segment.Mode.GetCharsCountBitsCount(version));
                bits.Add(segment.Data);
            }

            Debug.Assert(bits.Length == usedBits);

            int dataCapacityBits = ComputeCodewordsCount(version, correctionLevel) * 8;

            Debug.Assert(bits.Length <= dataCapacityBits);

            bits.Add(0, Math.Min(4, dataCapacityBits - bits.Length));
            bits.Add(0, (8 - bits.Length % 8) % 8);

            Debug.Assert(bits.Length % 8 == 0);

            for (int padByte = 0b11101100; bits.Length < dataCapacityBits; padByte ^= 0b11111101)
            {
                bits.Add(padByte, 8);
            }

            byte[] dataCodewords = new byte[bits.Length / 8];
            for (int i = 0; i < bits.Length; ++i)
            {
                int index = i >> 3;
                dataCodewords[index] = (byte)(dataCodewords[index] | (bits[i] << (7 - (i & 7))));
            }

            return(new QRCode(version, correctionLevel, dataCodewords, mask));
        }