diff --git a/QRCoder/QRCodeGenerator.ModulePlacer.MaskPattern.cs b/QRCoder/QRCodeGenerator.ModulePlacer.MaskPattern.cs index 61aae144..995dd54f 100644 --- a/QRCoder/QRCodeGenerator.ModulePlacer.MaskPattern.cs +++ b/QRCoder/QRCodeGenerator.ModulePlacer.MaskPattern.cs @@ -17,10 +17,10 @@ private static class MaskPattern /// /// A dictionary mapping each mask pattern index to its corresponding function that calculates whether a given pixel should be masked. /// - public static readonly Dictionary> Patterns = - new Dictionary>(8) { - { 1, MaskPattern.Pattern1 }, {2, MaskPattern.Pattern2 }, {3, MaskPattern.Pattern3 }, {4, MaskPattern.Pattern4 }, - { 5, MaskPattern.Pattern5 }, {6, MaskPattern.Pattern6 }, {7, MaskPattern.Pattern7 }, {8, MaskPattern.Pattern8 } + public static readonly List> Patterns = + new List>(8) { + MaskPattern.Pattern1, MaskPattern.Pattern2, MaskPattern.Pattern3, MaskPattern.Pattern4, + MaskPattern.Pattern5, MaskPattern.Pattern6, MaskPattern.Pattern7, MaskPattern.Pattern8 }; /// diff --git a/QRCoder/QRCodeGenerator.ModulePlacer.cs b/QRCoder/QRCodeGenerator.ModulePlacer.cs index 3b9c5434..d5fe88d9 100644 --- a/QRCoder/QRCodeGenerator.ModulePlacer.cs +++ b/QRCoder/QRCodeGenerator.ModulePlacer.cs @@ -107,8 +107,8 @@ public static void PlaceFormat(QRCodeData qrCode, BitArray formatStr, bool offse /// The index of the selected mask pattern. public static int MaskCode(QRCodeData qrCode, int version, BlockedModules blockedModules, ECCLevel eccLevel) { - int? selectedPattern = null; - var patternScore = 0; + int selectedPattern = -1; // no pattern selected yet + var patternScore = int.MaxValue; // lower score is better var size = qrCode.ModuleMatrix.Count - 8; @@ -121,8 +121,10 @@ public static int MaskCode(QRCodeData qrCode, int version, BlockedModules blocke GetVersionString(versionString, version); } var formatStr = new BitArray(15); - foreach (var pattern in MaskPattern.Patterns) + for (var maskPattern = 0; maskPattern < 8; maskPattern++) { + var patternFunc = MaskPattern.Patterns[maskPattern]; + // Reset the temporary QR code to the current state of the actual QR code. for (var y = 0; y < size; y++) { @@ -133,7 +135,7 @@ public static int MaskCode(QRCodeData qrCode, int version, BlockedModules blocke } // Place format information using the current mask pattern. - GetFormatString(formatStr, eccLevel, pattern.Key - 1); + GetFormatString(formatStr, eccLevel, maskPattern); ModulePlacer.PlaceFormat(qrTemp, formatStr, false); // Place version information if applicable. @@ -149,46 +151,47 @@ public static int MaskCode(QRCodeData qrCode, int version, BlockedModules blocke { if (!blockedModules.IsBlocked(x, y)) { - qrTemp.ModuleMatrix[y][x] ^= pattern.Value(x, y); - qrTemp.ModuleMatrix[x][y] ^= pattern.Value(y, x); + qrTemp.ModuleMatrix[y][x] ^= patternFunc(x, y); + qrTemp.ModuleMatrix[x][y] ^= patternFunc(y, x); } } if (!blockedModules.IsBlocked(x, x)) { - qrTemp.ModuleMatrix[x][x] ^= pattern.Value(x, x); + qrTemp.ModuleMatrix[x][x] ^= patternFunc(x, x); } } var score = MaskPattern.Score(qrTemp); // Select the pattern with the lowest score, indicating better QR code readability. - if (!selectedPattern.HasValue || patternScore > score) + if (patternScore > score) { - selectedPattern = pattern.Key; + selectedPattern = maskPattern; patternScore = score; } } // Apply the best mask pattern to the actual QR code. + var selectedPatternFunc = MaskPattern.Patterns[selectedPattern]; for (var x = 0; x < size; x++) { for (var y = 0; y < x; y++) { if (!blockedModules.IsBlocked(x, y)) { - qrCode.ModuleMatrix[y + 4][x + 4] ^= MaskPattern.Patterns[selectedPattern.Value](x, y); - qrCode.ModuleMatrix[x + 4][y + 4] ^= MaskPattern.Patterns[selectedPattern.Value](y, x); + qrCode.ModuleMatrix[y + 4][x + 4] ^= selectedPatternFunc(x, y); + qrCode.ModuleMatrix[x + 4][y + 4] ^= selectedPatternFunc(y, x); } } if (!blockedModules.IsBlocked(x, x)) { - qrCode.ModuleMatrix[x + 4][x + 4] ^= MaskPattern.Patterns[selectedPattern.Value](x, x); + qrCode.ModuleMatrix[x + 4][x + 4] ^= selectedPatternFunc(x, x); } } - return selectedPattern.Value - 1; + return selectedPattern; } ///