diff --git a/QRCoder/QRCodeData.cs b/QRCoder/QRCodeData.cs index b7f5df29..e9b8a571 100644 --- a/QRCoder/QRCodeData.cs +++ b/QRCoder/QRCodeData.cs @@ -17,7 +17,16 @@ public QRCodeData(int version) { this.Version = version; var size = ModulesPerSideFromVersion(version); - this.ModuleMatrix = new List(); + this.ModuleMatrix = new List(size); + for (var i = 0; i < size; i++) + this.ModuleMatrix.Add(new BitArray(size)); + } + + public QRCodeData(int version, bool addPadding) + { + this.Version = version; + var size = ModulesPerSideFromVersion(version) + (addPadding ? 8 : 0); + this.ModuleMatrix = new List(size); for (var i = 0; i < size; i++) this.ModuleMatrix.Add(new BitArray(size)); } diff --git a/QRCoder/QRCodeGenerator.ModulePlacer.BlockedModules.cs b/QRCoder/QRCodeGenerator.ModulePlacer.BlockedModules.cs new file mode 100644 index 00000000..555bc143 --- /dev/null +++ b/QRCoder/QRCodeGenerator.ModulePlacer.BlockedModules.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections; +using System.Threading; + +namespace QRCoder +{ + public partial class QRCodeGenerator + { + private static partial class ModulePlacer + { + /// + /// Struct that represents blocked modules using rectangles. + /// + public struct BlockedModules : IDisposable + { + private readonly BitArray[] _blockedModules; + + private static BitArray[] _staticBlockedModules; + + /// + /// Initializes a new instance of the struct with a specified capacity. + /// + /// The initial capacity of the blocked modules list. + public BlockedModules(int size) + { + _blockedModules = Interlocked.Exchange(ref _staticBlockedModules, null); + if (_blockedModules != null && _blockedModules.Length >= size) + { + for (int i = 0; i < size; i++) + _blockedModules[i].SetAll(false); + } + else + { + _blockedModules = new BitArray[size]; + for (int i = 0; i < size; i++) + _blockedModules[i] = new BitArray(size); + } + } + + /// + /// Adds a blocked module at the specified coordinates. + /// + /// The x-coordinate of the module. + /// The y-coordinate of the module. + public void Add(int x, int y) + { + _blockedModules[y][x] = true; + } + + /// + /// Adds a blocked module defined by the specified rectangle. + /// + /// The rectangle that defines the blocked module. + public void Add(Rectangle rect) + { + for (int y = rect.Y; y < rect.Y + rect.Height; y++) + { + for (int x = rect.X; x < rect.X + rect.Width; x++) + { + _blockedModules[y][x] = true; + } + } + } + + /// + /// Checks if the specified coordinates are blocked. + /// + /// The x-coordinate to check. + /// The y-coordinate to check. + /// true if the coordinates are blocked; otherwise, false. + public bool IsBlocked(int x, int y) + { + return _blockedModules[y][x]; + } + + /// + /// Checks if the specified rectangle is blocked. + /// + /// The rectangle to check. + /// true if the rectangle is blocked; otherwise, false. + public bool IsBlocked(Rectangle r1) + { + for (int y = r1.Y; y < r1.Y + r1.Height; y++) + { + for (int x = r1.X; x < r1.X + r1.Width; x++) + { + if (_blockedModules[y][x]) + return true; + } + } + return false; + } + + public void Dispose() + { + Interlocked.CompareExchange(ref _staticBlockedModules, _blockedModules, null); + } + } + } + } +} diff --git a/QRCoder/QRCodeGenerator.ModulePlacer.cs b/QRCoder/QRCodeGenerator.ModulePlacer.cs index 28196f4f..3b9c5434 100644 --- a/QRCoder/QRCodeGenerator.ModulePlacer.cs +++ b/QRCoder/QRCodeGenerator.ModulePlacer.cs @@ -17,16 +17,13 @@ private static partial class ModulePlacer public static void AddQuietZone(QRCodeData qrCode) { // Calculate the required length for a new quiet line, including existing modules plus 8 additional for the quiet zone. - var quietLine = new bool[qrCode.ModuleMatrix.Count + 8]; - // Initialize the quiet line with false values to represent white modules. - for (var i = 0; i < quietLine.Length; i++) - quietLine[i] = false; + var quietLineLength = qrCode.ModuleMatrix.Count + 8; // Add four new lines at the top of the QR code matrix to create the upper part of the quiet zone. for (var i = 0; i < 4; i++) - qrCode.ModuleMatrix.Insert(0, new BitArray(quietLine)); + qrCode.ModuleMatrix.Insert(0, new BitArray(quietLineLength)); // Add four new lines at the bottom of the QR code matrix to create the lower part of the quiet zone. for (var i = 0; i < 4; i++) - qrCode.ModuleMatrix.Add(new BitArray(quietLine)); + qrCode.ModuleMatrix.Add(new BitArray(quietLineLength)); // Expand each line of the QR code matrix sideways by 4 modules on each side to complete the quiet zone. for (var i = 4; i < qrCode.ModuleMatrix.Count - 4; i++) { @@ -41,9 +38,10 @@ public static void AddQuietZone(QRCodeData qrCode) /// /// The QR code data structure to modify. /// The bit array containing the version information. - public static void PlaceVersion(QRCodeData qrCode, BitArray versionStr) + public static void PlaceVersion(QRCodeData qrCode, BitArray versionStr, bool offset) { - var size = qrCode.ModuleMatrix.Count; + var offsetValue = offset ? 4 : 0; + var size = qrCode.ModuleMatrix.Count - offsetValue - offsetValue; // Loop through each module position intended for version information, placed adjacent to the separators. for (var x = 0; x < 6; x++) @@ -51,8 +49,8 @@ public static void PlaceVersion(QRCodeData qrCode, BitArray versionStr) for (var y = 0; y < 3; y++) { // Apply the version bits to the corresponding modules on the matrix, mapping the bits from the versionStr array. - qrCode.ModuleMatrix[y + size - 11][x] = versionStr[17 - (x * 3 + y)]; - qrCode.ModuleMatrix[x][y + size - 11] = versionStr[17 - (x * 3 + y)]; + qrCode.ModuleMatrix[y + size - 11 + offsetValue][x + offsetValue] = versionStr[17 - (x * 3 + y)]; + qrCode.ModuleMatrix[x + offsetValue][y + size - 11 + offsetValue] = versionStr[17 - (x * 3 + y)]; } } } @@ -62,9 +60,10 @@ public static void PlaceVersion(QRCodeData qrCode, BitArray versionStr) /// /// The QR code data structure to modify. /// The bit array containing the format information. - public static void PlaceFormat(QRCodeData qrCode, BitArray formatStr) + public static void PlaceFormat(QRCodeData qrCode, BitArray formatStr, bool offset) { - var size = qrCode.ModuleMatrix.Count; + var offsetValue = offset ? 4 : 0; + var size = qrCode.ModuleMatrix.Count - offsetValue - offsetValue; // { x1, y1, x2, y2 } i // =============================== @@ -92,8 +91,8 @@ public static void PlaceFormat(QRCodeData qrCode, BitArray formatStr) var x2 = i < 8 ? size - 1 - i : 8; var y2 = i < 8 ? 8 : size - (15 - i); - qrCode.ModuleMatrix[y1][x1] = formatStr[14 - i]; - qrCode.ModuleMatrix[y2][x2] = formatStr[14 - i]; + qrCode.ModuleMatrix[y1 + offsetValue][x1 + offsetValue] = formatStr[14 - i]; + qrCode.ModuleMatrix[y2 + offsetValue][x2 + offsetValue] = formatStr[14 - i]; } } @@ -106,15 +105,22 @@ public static void PlaceFormat(QRCodeData qrCode, BitArray formatStr) /// List of rectangles representing areas that must not be overwritten. /// The error correction level of the QR code, which affects format string values. /// The index of the selected mask pattern. - public static int MaskCode(QRCodeData qrCode, int version, List blockedModules, ECCLevel eccLevel) + public static int MaskCode(QRCodeData qrCode, int version, BlockedModules blockedModules, ECCLevel eccLevel) { int? selectedPattern = null; var patternScore = 0; - var size = qrCode.ModuleMatrix.Count; + var size = qrCode.ModuleMatrix.Count - 8; // Temporary QRCodeData object to test different mask patterns without altering the original. - var qrTemp = new QRCodeData(version); + var qrTemp = new QRCodeData(version, false); + BitArray versionString = null; + if (version >= 7) + { + versionString = new BitArray(18); + GetVersionString(versionString, version); + } + var formatStr = new BitArray(15); foreach (var pattern in MaskPattern.Patterns) { // Reset the temporary QR code to the current state of the actual QR code. @@ -122,19 +128,18 @@ public static int MaskCode(QRCodeData qrCode, int version, List block { for (var x = 0; x < size; x++) { - qrTemp.ModuleMatrix[y][x] = qrCode.ModuleMatrix[y][x]; + qrTemp.ModuleMatrix[y][x] = qrCode.ModuleMatrix[y + 4][x + 4]; } } // Place format information using the current mask pattern. - var formatStr = GetFormatString(eccLevel, pattern.Key - 1); - ModulePlacer.PlaceFormat(qrTemp, formatStr); + GetFormatString(formatStr, eccLevel, pattern.Key - 1); + ModulePlacer.PlaceFormat(qrTemp, formatStr, false); // Place version information if applicable. if (version >= 7) { - var versionString = GetVersionString(version); - ModulePlacer.PlaceVersion(qrTemp, versionString); + ModulePlacer.PlaceVersion(qrTemp, versionString, false); } // Apply the mask pattern and calculate the score. @@ -142,14 +147,14 @@ public static int MaskCode(QRCodeData qrCode, int version, List block { for (var y = 0; y < x; y++) { - if (!IsBlocked(new Rectangle(x, y, 1, 1), blockedModules)) + if (!blockedModules.IsBlocked(x, y)) { qrTemp.ModuleMatrix[y][x] ^= pattern.Value(x, y); qrTemp.ModuleMatrix[x][y] ^= pattern.Value(y, x); } } - if (!IsBlocked(new Rectangle(x, x, 1, 1), blockedModules)) + if (!blockedModules.IsBlocked(x, x)) { qrTemp.ModuleMatrix[x][x] ^= pattern.Value(x, x); } @@ -170,18 +175,19 @@ public static int MaskCode(QRCodeData qrCode, int version, List block { for (var y = 0; y < x; y++) { - if (!IsBlocked(new Rectangle(x, y, 1, 1), blockedModules)) + if (!blockedModules.IsBlocked(x, y)) { - qrCode.ModuleMatrix[y][x] ^= MaskPattern.Patterns[selectedPattern.Value](x, y); - qrCode.ModuleMatrix[x][y] ^= MaskPattern.Patterns[selectedPattern.Value](y, x); + qrCode.ModuleMatrix[y + 4][x + 4] ^= MaskPattern.Patterns[selectedPattern.Value](x, y); + qrCode.ModuleMatrix[x + 4][y + 4] ^= MaskPattern.Patterns[selectedPattern.Value](y, x); } } - if (!IsBlocked(new Rectangle(x, x, 1, 1), blockedModules)) + if (!blockedModules.IsBlocked(x, x)) { - qrCode.ModuleMatrix[x][x] ^= MaskPattern.Patterns[selectedPattern.Value](x, x); + qrCode.ModuleMatrix[x + 4][x + 4] ^= MaskPattern.Patterns[selectedPattern.Value](x, x); } } + return selectedPattern.Value - 1; } @@ -191,9 +197,9 @@ public static int MaskCode(QRCodeData qrCode, int version, List block /// The QR code data structure where the data bits are to be placed. /// The data bits to be placed within the QR code matrix. /// A list of rectangles representing areas within the QR code matrix that should not be modified because they contain other necessary information like format and version info. - public static void PlaceDataWords(QRCodeData qrCode, BitArray data, List blockedModules) + public static void PlaceDataWords(QRCodeData qrCode, BitArray data, BlockedModules blockedModules) { - var size = qrCode.ModuleMatrix.Count; // Get the size of the QR code matrix. + var size = qrCode.ModuleMatrix.Count - 8; // Get the size of the QR code matrix. var up = true; // A boolean flag used to alternate the direction of filling data: up or down. var index = 0; // Index to track the current bit position in the data BitArray. var count = data.Length; // Total number of data bits to place. @@ -215,19 +221,19 @@ public static void PlaceDataWords(QRCodeData qrCode, BitArray data, List 0 && !IsBlocked(new Rectangle(x - 1, y, 1, 1), blockedModules)) - qrCode.ModuleMatrix[y][x - 1] = data[index++]; + if (index < count && !blockedModules.IsBlocked(x, y)) + qrCode.ModuleMatrix[y + 4][x + 4] = data[index++]; + if (index < count && x > 0 && !blockedModules.IsBlocked(x - 1, y)) + qrCode.ModuleMatrix[y + 4][x - 1 + 4] = data[index++]; } else { y = yMod - 1; // Calculate y for downward direction. // Similar checks and data placement for the downward direction. - if (index < count && !IsBlocked(new Rectangle(x, y, 1, 1), blockedModules)) - qrCode.ModuleMatrix[y][x] = data[index++]; - if (index < count && x > 0 && !IsBlocked(new Rectangle(x - 1, y, 1, 1), blockedModules)) - qrCode.ModuleMatrix[y][x - 1] = data[index++]; + if (index < count && !blockedModules.IsBlocked(x, y)) + qrCode.ModuleMatrix[y + 4][x + 4] = data[index++]; + if (index < count && x > 0 && !blockedModules.IsBlocked(x - 1, y)) + qrCode.ModuleMatrix[y + 4][x - 1 + 4] = data[index++]; } } // Switch the fill direction after completing each column set. @@ -240,7 +246,7 @@ public static void PlaceDataWords(QRCodeData qrCode, BitArray data, List /// The size of the QR code matrix. /// A list of rectangles representing areas that must not be overwritten. - public static void ReserveSeperatorAreas(int size, List blockedModules) + public static void ReserveSeperatorAreas(int size, BlockedModules blockedModules) { // Block areas around the finder patterns, which are located near three corners of the QR code. blockedModules.Add(new Rectangle(7, 0, 1, 8)); // Vertical block near the top left finder pattern @@ -257,7 +263,7 @@ public static void ReserveSeperatorAreas(int size, List blockedModule /// The size of the QR code matrix. /// The version number of the QR code, which determines the placement of version information. /// A list of rectangles representing areas that must not be overwritten. - public static void ReserveVersionAreas(int size, int version, List blockedModules) + public static void ReserveVersionAreas(int size, int version, BlockedModules blockedModules) { // Reserve areas near the timing patterns for version and format information. blockedModules.Add(new Rectangle(8, 0, 1, 6)); // Near the top timing pattern @@ -281,10 +287,10 @@ public static void ReserveVersionAreas(int size, int version, List bl /// The QR code data structure where the dark module is to be placed. /// The version number of the QR code, which determines the specific location of the dark module. /// A list of rectangles representing areas that must not be overwritten, updated to include the dark module. - public static void PlaceDarkModule(QRCodeData qrCode, int version, List blockedModules) + public static void PlaceDarkModule(QRCodeData qrCode, int version, BlockedModules blockedModules) { // Place the dark module, which is always required to be black. - qrCode.ModuleMatrix[4 * version + 9][8] = true; + qrCode.ModuleMatrix[4 * version + 9 + 4][8 + 4] = true; // Block the dark module area to prevent overwriting during further QR code generation steps. blockedModules.Add(new Rectangle(8, 4 * version + 9, 1, 1)); } @@ -294,9 +300,9 @@ public static void PlaceDarkModule(QRCodeData qrCode, int version, List /// The QR code data structure where the finder patterns will be placed. /// A list of rectangles representing areas that must not be overwritten. This is updated with the areas occupied by the finder patterns. - public static void PlaceFinderPatterns(QRCodeData qrCode, List blockedModules) + public static void PlaceFinderPatterns(QRCodeData qrCode, BlockedModules blockedModules) { - var size = qrCode.ModuleMatrix.Count; + var size = qrCode.ModuleMatrix.Count - 8; // Loop to place three finder patterns in the top-left, top-right, and bottom-left corners of the QR code. for (var i = 0; i < 3; i++) @@ -314,7 +320,7 @@ public static void PlaceFinderPatterns(QRCodeData qrCode, List blocke // The center 3x3 area is filled, bordered by a line of white modules, enclosed by a 7x7 black border. if (!(((x == 1 || x == 5) && y > 0 && y < 6) || (x > 0 && x < 6 && (y == 1 || y == 5)))) { - qrCode.ModuleMatrix[y + locationY][x + locationX] = true; + qrCode.ModuleMatrix[y + locationY + 4][x + locationX + 4] = true; } } } @@ -330,28 +336,20 @@ public static void PlaceFinderPatterns(QRCodeData qrCode, List blocke /// The QR code data structure where the alignment patterns will be placed. /// A list of points representing the centers of where alignment patterns should be placed. /// A list of rectangles representing areas that must not be overwritten. Updated with the areas occupied by alignment patterns. - public static void PlaceAlignmentPatterns(QRCodeData qrCode, List alignmentPatternLocations, List blockedModules) + public static void PlaceAlignmentPatterns(QRCodeData qrCode, List alignmentPatternLocations, BlockedModules blockedModules) { // Iterate through each specified location for alignment patterns. foreach (var loc in alignmentPatternLocations) { // Define a 5x5 rectangle for the alignment pattern based on the center point provided. var alignmentPatternRect = new Rectangle(loc.X, loc.Y, 5, 5); - var blocked = false; // Flag to check if the current location overlaps with any blocked modules. // Check if the proposed alignment pattern rectangle intersects with any already blocked rectangles. - foreach (var blockedRect in blockedModules) + if (blockedModules.IsBlocked(alignmentPatternRect)) { - if (Intersects(alignmentPatternRect, blockedRect)) - { - blocked = true; - break; // Stop checking if an intersection is found and mark this location as blocked. - } - } - - // Skip the current location if it is blocked to prevent overwriting crucial information. - if (blocked) + // Skip the current location if it is blocked to prevent overwriting crucial information. continue; + } // Place the alignment pattern by setting modules within the 5x5 area. // The pattern consists of a 3x3 center block with a single module border. @@ -362,7 +360,7 @@ public static void PlaceAlignmentPatterns(QRCodeData qrCode, List alignme // Create the pattern: a 3x3 block surrounded by a border, with the very center module set. if (y == 0 || y == 4 || x == 0 || x == 4 || (x == 2 && y == 2)) { - qrCode.ModuleMatrix[loc.Y + y][loc.X + x] = true; + qrCode.ModuleMatrix[loc.Y + y + 4][loc.X + x + 4] = true; } } } @@ -377,17 +375,17 @@ public static void PlaceAlignmentPatterns(QRCodeData qrCode, List alignme /// /// The QR code data structure where the timing patterns will be placed. /// A list of rectangles representing areas that must not be overwritten. Updated with the areas occupied by timing patterns. - public static void PlaceTimingPatterns(QRCodeData qrCode, List blockedModules) + public static void PlaceTimingPatterns(QRCodeData qrCode, BlockedModules blockedModules) { - var size = qrCode.ModuleMatrix.Count; // Get the size of the QR code matrix. + var size = qrCode.ModuleMatrix.Count - 8; // Get the size of the QR code matrix. // Place timing patterns starting from the 8th module to the size - 8 to avoid overlapping with finder patterns. for (var i = 8; i < size - 8; i++) { if (i % 2 == 0) // Place a dark module every other module to create the alternating pattern. { - qrCode.ModuleMatrix[6][i] = true; // Horizontal timing pattern - qrCode.ModuleMatrix[i][6] = true; // Vertical timing pattern + qrCode.ModuleMatrix[6 + 4][i + 4] = true; // Horizontal timing pattern + qrCode.ModuleMatrix[i + 4][6 + 4] = true; // Vertical timing pattern } } @@ -395,31 +393,6 @@ public static void PlaceTimingPatterns(QRCodeData qrCode, List blocke blockedModules.Add(new Rectangle(6, 8, 1, size - 16)); // Horizontal timing pattern area blockedModules.Add(new Rectangle(8, 6, size - 16, 1)); // Vertical timing pattern area } - - /// - /// Determines if two rectangles intersect with each other. - /// - private static bool Intersects(Rectangle r1, Rectangle r2) - { - // Check if any part of the rectangles overlap. - return r2.X < r1.X + r1.Width && r1.X < r2.X + r2.Width && r2.Y < r1.Y + r1.Height && r1.Y < r2.Y + r2.Height; - } - - /// - /// Checks if a given rectangle is blocked by any rectangle in a list of blocked modules. - /// - /// The rectangle to check. - /// The list of rectangles representing blocked areas. - private static bool IsBlocked(Rectangle r1, List blockedModules) - { - // Iterate through the list of blocked modules to check for any intersection. - foreach (var blockedMod in blockedModules) - { - if (Intersects(blockedMod, r1)) - return true; - } - return false; - } } } } diff --git a/QRCoder/QRCodeGenerator.cs b/QRCoder/QRCodeGenerator.cs index b12f7221..f8da2bf6 100644 --- a/QRCoder/QRCodeGenerator.cs +++ b/QRCoder/QRCodeGenerator.cs @@ -345,26 +345,28 @@ BitArray InterleaveData() // Place the modules on the QR code matrix QRCodeData PlaceModules() { - var qr = new QRCodeData(version); - var blockedModules = new List(17); - ModulePlacer.PlaceFinderPatterns(qr, blockedModules); - ModulePlacer.ReserveSeperatorAreas(qr.ModuleMatrix.Count, blockedModules); - ModulePlacer.PlaceAlignmentPatterns(qr, alignmentPatternTable[version].PatternPositions, blockedModules); - ModulePlacer.PlaceTimingPatterns(qr, blockedModules); - ModulePlacer.PlaceDarkModule(qr, version, blockedModules); - ModulePlacer.ReserveVersionAreas(qr.ModuleMatrix.Count, version, blockedModules); - ModulePlacer.PlaceDataWords(qr, interleavedData, blockedModules); - var maskVersion = ModulePlacer.MaskCode(qr, version, blockedModules, eccLevel); - var formatStr = GetFormatString(eccLevel, maskVersion); - - ModulePlacer.PlaceFormat(qr, formatStr); - if (version >= 7) + var qr = new QRCodeData(version, true); + var size = qr.ModuleMatrix.Count - 8; + var tempBitArray = new BitArray(18); //version string requires 18 bits + using (var blockedModules = new ModulePlacer.BlockedModules(size)) { - var versionString = GetVersionString(version); - ModulePlacer.PlaceVersion(qr, versionString); + ModulePlacer.PlaceFinderPatterns(qr, blockedModules); + ModulePlacer.ReserveSeperatorAreas(size, blockedModules); + ModulePlacer.PlaceAlignmentPatterns(qr, alignmentPatternTable[version].PatternPositions, blockedModules); + ModulePlacer.PlaceTimingPatterns(qr, blockedModules); + ModulePlacer.PlaceDarkModule(qr, version, blockedModules); + ModulePlacer.ReserveVersionAreas(size, version, blockedModules); + ModulePlacer.PlaceDataWords(qr, interleavedData, blockedModules); + var maskVersion = ModulePlacer.MaskCode(qr, version, blockedModules, eccLevel); + GetFormatString(tempBitArray, eccLevel, maskVersion); + ModulePlacer.PlaceFormat(qr, tempBitArray, true); } - ModulePlacer.AddQuietZone(qr); + if (version >= 7) + { + GetVersionString(tempBitArray, version); + ModulePlacer.PlaceVersion(qr, tempBitArray, true); + } return qr; } @@ -376,12 +378,14 @@ QRCodeData PlaceModules() /// Generates a BitArray containing the format string for a QR code based on the error correction level and mask pattern version. /// The format string includes the error correction level, mask pattern version, and error correction coding. /// + /// The to write to, or null to create a new one. /// The error correction level to be encoded in the format string. /// The mask pattern version to be encoded in the format string. /// A BitArray containing the 15-bit format string used in QR code generation. - private static BitArray GetFormatString(ECCLevel level, int maskVersion) + private static void GetFormatString(BitArray fStrEcc, ECCLevel level, int maskVersion) { - var fStrEcc = new BitArray(15); // Total length including space for mask version and padding + fStrEcc.Length = 15; + fStrEcc.SetAll(false); WriteEccLevelAndVersion(); // Apply the format generator polynomial to add error correction to the format string. @@ -405,7 +409,6 @@ private static BitArray GetFormatString(ECCLevel level, int maskVersion) // XOR the format string with a predefined mask to add robustness against errors. fStrEcc.Xor(_getFormatMask); - return fStrEcc; void WriteEccLevelAndVersion() { @@ -472,11 +475,13 @@ private static void ShiftAwayFromBit0(BitArray fStrEcc, int num) /// Encodes the version information of a QR code into a BitArray using error correction coding similar to format information encoding. /// This method is used for QR codes version 7 and above. /// + /// A to write the version string to. /// The version number of the QR code (7-40). /// A BitArray containing the encoded version information, which includes error correction bits. - private static BitArray GetVersionString(int version) + private static void GetVersionString(BitArray vStr, int version) { - var vStr = new BitArray(18); + vStr.Length = 18; + vStr.SetAll(false); DecToBin(version, 6, vStr, 0); // Convert the version number to a 6-bit binary representation. var count = vStr.Length; @@ -498,8 +503,6 @@ private static BitArray GetVersionString(int version) vStr.Length = 12 + 6; ShiftAwayFromBit0(vStr, (12 - count) + 6); DecToBin(version, 6, vStr, 0); - - return vStr; } /// diff --git a/QRCoderApiTests/net35+net40+net50+net50-windows+netstandard20/QRCoder.approved.txt b/QRCoderApiTests/net35+net40+net50+net50-windows+netstandard20/QRCoder.approved.txt index 60b1ecc2..fb75ea56 100644 --- a/QRCoderApiTests/net35+net40+net50+net50-windows+netstandard20/QRCoder.approved.txt +++ b/QRCoderApiTests/net35+net40+net50+net50-windows+netstandard20/QRCoder.approved.txt @@ -868,6 +868,7 @@ namespace QRCoder { public QRCodeData(int version) { } public QRCodeData(byte[] rawData, QRCoder.QRCodeData.Compression compressMode) { } + public QRCodeData(int version, bool addPadding) { } public QRCodeData(string pathToRawData, QRCoder.QRCodeData.Compression compressMode) { } public System.Collections.Generic.List ModuleMatrix { get; set; } public int Version { get; } diff --git a/QRCoderApiTests/net60-windows/QRCoder.approved.txt b/QRCoderApiTests/net60-windows/QRCoder.approved.txt index ff07d0df..84343d9a 100644 --- a/QRCoderApiTests/net60-windows/QRCoder.approved.txt +++ b/QRCoderApiTests/net60-windows/QRCoder.approved.txt @@ -876,6 +876,7 @@ namespace QRCoder { public QRCodeData(int version) { } public QRCodeData(byte[] rawData, QRCoder.QRCodeData.Compression compressMode) { } + public QRCodeData(int version, bool addPadding) { } public QRCodeData(string pathToRawData, QRCoder.QRCodeData.Compression compressMode) { } public System.Collections.Generic.List ModuleMatrix { get; set; } public int Version { get; } diff --git a/QRCoderApiTests/net60/QRCoder.approved.txt b/QRCoderApiTests/net60/QRCoder.approved.txt index e558ea6f..6368686e 100644 --- a/QRCoderApiTests/net60/QRCoder.approved.txt +++ b/QRCoderApiTests/net60/QRCoder.approved.txt @@ -810,6 +810,7 @@ namespace QRCoder { public QRCodeData(int version) { } public QRCodeData(byte[] rawData, QRCoder.QRCodeData.Compression compressMode) { } + public QRCodeData(int version, bool addPadding) { } public QRCodeData(string pathToRawData, QRCoder.QRCodeData.Compression compressMode) { } public System.Collections.Generic.List ModuleMatrix { get; set; } public int Version { get; } diff --git a/QRCoderApiTests/netstandard13/QRCoder.approved.txt b/QRCoderApiTests/netstandard13/QRCoder.approved.txt index 34362e64..4ceeaf4f 100644 --- a/QRCoderApiTests/netstandard13/QRCoder.approved.txt +++ b/QRCoderApiTests/netstandard13/QRCoder.approved.txt @@ -775,6 +775,7 @@ namespace QRCoder { public QRCodeData(int version) { } public QRCodeData(byte[] rawData, QRCoder.QRCodeData.Compression compressMode) { } + public QRCodeData(int version, bool addPadding) { } public QRCodeData(string pathToRawData, QRCoder.QRCodeData.Compression compressMode) { } public System.Collections.Generic.List ModuleMatrix { get; set; } public int Version { get; }