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;
}
///