private static int ComputeCodewordsCount(int version, CorrectionLevel correctionLevel) { Debug.Assert(version >= MinVersion && version <= MaxVersion); Debug.Assert(correctionLevel != null); return(ComputeRawDataModulesCount(version) / 8 - CodewordsPerBlock[correctionLevel.Id][version] * CorrectionBlocksCount[correctionLevel.Id][version]); }
public QRCode(int version, CorrectionLevel correctionLevel, byte[] data, Mask mask) { if (version < MinVersion || version > MaxVersion) { throw new ArgumentOutOfRangeException(nameof(version)); } if (correctionLevel is null) { throw new ArgumentNullException(nameof(correctionLevel)); } if (data is null) { throw new ArgumentNullException(nameof(data)); } Version = version; Size = ComputeSize(version); CorrectionLevel = correctionLevel; Modules = new bool[Size, Size]; Specials = new bool[Size, Size]; DrawFunctionPatterns(); DrawCodewords(AddCorrectionBlocksAndStraighten(data)); Mask = ApplyMask(mask); }
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)); }
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)); }
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)); }
public static QRCode EncodeSegments(IEnumerable <QRSegment> segments, CorrectionLevel correctionLevel) => EncodeSegments(segments, correctionLevel, MinVersion, MaxVersion, -1, true);