Example #1
0
        public static QrCode EncodeSegments(List <QrSegment> segs, Ecc ecl, int minVersion, int maxVersion, int mask, bool boostEcl)
        {
            Utils.CheckNull(segs, nameof(segs));

            if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7)
            {
                throw new ArgumentException("Invalid value");
            }

            int version, dataUsedBits;

            for (version = minVersion; ; version++)
            {
                var capacityBits = GetNumDataCodewords(version, ecl) * 8;
                dataUsedBits = QrSegment.GetTotalBits(segs, version);
                if (dataUsedBits != -1 && dataUsedBits <= capacityBits)
                {
                    break;
                }

                if (version >= maxVersion)
                {
                    var msg = "Segment too long";
                    if (dataUsedBits != -1)
                    {
                        msg = string.Format("Data length = {0} bits, Max capacity = {1} bits", dataUsedBits, capacityBits);
                    }
                    throw new DataTooLongException(msg);
                }
            }

            foreach (var newEcl in new Ecc[] { Ecc.Low, Ecc.Medium, Ecc.Quartitle, Ecc.High })
            {
                if (boostEcl && dataUsedBits <= GetNumDataCodewords(version, newEcl) * 8)
                {
                    ecl = newEcl;
                }
            }

            var bb = new BitBuffer();

            foreach (var seg in segs)
            {
                bb.AppendBits(seg.Mode.ModeBits, 4);
                bb.AppendBits(seg.NumChars, seg.Mode.NumCharCountBits(version));
                bb.AppendData(seg.Data);
            }

            var dataCapacityBits = GetNumDataCodewords(version, ecl) * 8;

            bb.AppendBits(0, Math.Min(4, dataCapacityBits - bb.Length));
            bb.AppendBits(0, (8 - bb.Length % 8) % 8);

            for (var padByte = 0xEC; bb.Length < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
            {
                bb.AppendBits(padByte, 8);
            }

            var dataCodewords = new byte[bb.Length / 8];

            for (var i = 0; i < bb.Length; i++)
            {
                dataCodewords[i >> 3] = (byte)(dataCodewords[i >> 3] | bb.GetBit(i) << (7 - (i & 7)));
            }

            // Create the QR Code object
            return(new QrCode(version, ecl, dataCodewords, mask));
        }