tidy
This commit is contained in:
+28
-30
@@ -1,36 +1,34 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Gma.QrCodeNet.Encoding.Masking.Scoring;
|
||||
|
||||
internal static class MatrixScoreCalculator
|
||||
{
|
||||
internal static BitMatrix GetLowestPenaltyMatrix(this TriStateMatrix matrix, ErrorCorrectionLevel errorLevel)
|
||||
{
|
||||
PatternFactory patternFactory = new();
|
||||
int score = int.MaxValue;
|
||||
int tempScore;
|
||||
TriStateMatrix result = new(matrix.Width);
|
||||
TriStateMatrix triMatrix;
|
||||
foreach (Pattern pattern in patternFactory.AllPatterns())
|
||||
{
|
||||
triMatrix = matrix.Apply(pattern, errorLevel);
|
||||
tempScore = triMatrix.PenaltyScore();
|
||||
if (tempScore < score)
|
||||
{
|
||||
score = tempScore;
|
||||
result = triMatrix;
|
||||
}
|
||||
}
|
||||
internal static BitMatrix GetLowestPenaltyMatrix(this TriStateMatrix matrix, ErrorCorrectionLevel errorLevel)
|
||||
{
|
||||
PatternFactory patternFactory = new();
|
||||
int score = int.MaxValue;
|
||||
int tempScore;
|
||||
TriStateMatrix result = new(matrix.Width);
|
||||
TriStateMatrix triMatrix;
|
||||
foreach (Pattern pattern in patternFactory.AllPatterns())
|
||||
{
|
||||
triMatrix = matrix.Apply(pattern, errorLevel);
|
||||
tempScore = triMatrix.PenaltyScore();
|
||||
if (tempScore < score)
|
||||
{
|
||||
score = tempScore;
|
||||
result = triMatrix;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static int PenaltyScore(this BitMatrix matrix)
|
||||
{
|
||||
PenaltyFactory penaltyFactory = new();
|
||||
return
|
||||
penaltyFactory
|
||||
.AllRules()
|
||||
.Sum(penalty => penalty.PenaltyCalculate(matrix));
|
||||
}
|
||||
}
|
||||
internal static int PenaltyScore(this BitMatrix matrix)
|
||||
{
|
||||
PenaltyFactory penaltyFactory = new();
|
||||
return
|
||||
penaltyFactory
|
||||
.AllRules()
|
||||
.Sum(penalty => penalty.PenaltyCalculate(matrix));
|
||||
}
|
||||
}
|
||||
@@ -2,5 +2,5 @@ namespace Gma.QrCodeNet.Encoding.Masking.Scoring;
|
||||
|
||||
public abstract class Penalty
|
||||
{
|
||||
internal abstract int PenaltyCalculate(BitMatrix matrix);
|
||||
}
|
||||
internal abstract int PenaltyCalculate(BitMatrix matrix);
|
||||
}
|
||||
@@ -5,81 +5,81 @@ namespace Gma.QrCodeNet.Encoding.Masking.Scoring;
|
||||
/// </summary>
|
||||
internal class Penalty1 : Penalty
|
||||
{
|
||||
/// <summary>
|
||||
/// Calculate penalty value for first rule.
|
||||
/// </summary>
|
||||
internal override int PenaltyCalculate(BitMatrix matrix)
|
||||
{
|
||||
int penaltyValue = PenaltyCalculation(matrix, true) + PenaltyCalculation(matrix, false);
|
||||
return penaltyValue;
|
||||
}
|
||||
/// <summary>
|
||||
/// Calculate penalty value for first rule.
|
||||
/// </summary>
|
||||
internal override int PenaltyCalculate(BitMatrix matrix)
|
||||
{
|
||||
int penaltyValue = PenaltyCalculation(matrix, true) + PenaltyCalculation(matrix, false);
|
||||
return penaltyValue;
|
||||
}
|
||||
|
||||
private int PenaltyCalculation(BitMatrix matrix, bool isHorizontal)
|
||||
{
|
||||
int penalty = 0;
|
||||
int width = matrix.Width;
|
||||
private int PenaltyCalculation(BitMatrix matrix, bool isHorizontal)
|
||||
{
|
||||
int penalty = 0;
|
||||
int width = matrix.Width;
|
||||
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
while (i < width)
|
||||
{
|
||||
while (j < width - 4)
|
||||
{
|
||||
bool preBit = isHorizontal
|
||||
? matrix[j + 4, i]
|
||||
: matrix[i, j + 4];
|
||||
int numSameBitCell = 1;
|
||||
while (i < width)
|
||||
{
|
||||
while (j < width - 4)
|
||||
{
|
||||
bool preBit = isHorizontal
|
||||
? matrix[j + 4, i]
|
||||
: matrix[i, j + 4];
|
||||
int numSameBitCell = 1;
|
||||
|
||||
for (int x = 1; x <= 4; x++)
|
||||
{
|
||||
bool bit = isHorizontal
|
||||
? matrix[j + 4 - x, i]
|
||||
: matrix[i, j + 4 - x];
|
||||
if (bit == preBit)
|
||||
{
|
||||
numSameBitCell++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int x = 1; x <= 4; x++)
|
||||
{
|
||||
bool bit = isHorizontal
|
||||
? matrix[j + 4 - x, i]
|
||||
: matrix[i, j + 4 - x];
|
||||
if (bit == preBit)
|
||||
{
|
||||
numSameBitCell++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (numSameBitCell == 1)
|
||||
{
|
||||
j += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
int x = 5;
|
||||
while ((j + x) < width)
|
||||
{
|
||||
bool bit = isHorizontal
|
||||
? matrix[j + x, i]
|
||||
: matrix[i, j + x];
|
||||
if (bit == preBit)
|
||||
{
|
||||
numSameBitCell++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
x++;
|
||||
}
|
||||
if (numSameBitCell >= 5)
|
||||
{
|
||||
penalty += (3 + (numSameBitCell - 5));
|
||||
}
|
||||
if (numSameBitCell == 1)
|
||||
{
|
||||
j += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
int x = 5;
|
||||
while ((j + x) < width)
|
||||
{
|
||||
bool bit = isHorizontal
|
||||
? matrix[j + x, i]
|
||||
: matrix[i, j + x];
|
||||
if (bit == preBit)
|
||||
{
|
||||
numSameBitCell++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
x++;
|
||||
}
|
||||
if (numSameBitCell >= 5)
|
||||
{
|
||||
penalty += (3 + (numSameBitCell - 5));
|
||||
}
|
||||
|
||||
j += x;
|
||||
}
|
||||
}
|
||||
j = 0;
|
||||
i++;
|
||||
}
|
||||
j += x;
|
||||
}
|
||||
}
|
||||
j = 0;
|
||||
i++;
|
||||
}
|
||||
|
||||
return penalty;
|
||||
}
|
||||
}
|
||||
return penalty;
|
||||
}
|
||||
}
|
||||
@@ -5,47 +5,47 @@ namespace Gma.QrCodeNet.Encoding.Masking.Scoring;
|
||||
/// </summary>
|
||||
internal class Penalty2 : Penalty
|
||||
{
|
||||
internal override int PenaltyCalculate(BitMatrix matrix)
|
||||
{
|
||||
int width = matrix.Width;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int penalty = 0;
|
||||
internal override int PenaltyCalculate(BitMatrix matrix)
|
||||
{
|
||||
int width = matrix.Width;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int penalty = 0;
|
||||
|
||||
while (y < (width - 1))
|
||||
{
|
||||
while (x < (width - 1))
|
||||
{
|
||||
bool topR = matrix[x + 1, y];
|
||||
while (y < (width - 1))
|
||||
{
|
||||
while (x < (width - 1))
|
||||
{
|
||||
bool topR = matrix[x + 1, y];
|
||||
|
||||
if (topR == matrix[x + 1, y + 1]) // Bottom Right
|
||||
{
|
||||
if (topR == matrix[x, y + 1]) // Bottom Left
|
||||
{
|
||||
if (topR == matrix[x, y]) // Top Left
|
||||
{
|
||||
penalty += 3;
|
||||
x += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x += 2;
|
||||
}
|
||||
}
|
||||
if (topR == matrix[x + 1, y + 1]) // Bottom Right
|
||||
{
|
||||
if (topR == matrix[x, y + 1]) // Bottom Left
|
||||
{
|
||||
if (topR == matrix[x, y]) // Top Left
|
||||
{
|
||||
penalty += 3;
|
||||
x += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x += 2;
|
||||
}
|
||||
}
|
||||
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
return penalty;
|
||||
}
|
||||
}
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
return penalty;
|
||||
}
|
||||
}
|
||||
@@ -5,137 +5,137 @@ namespace Gma.QrCodeNet.Encoding.Masking.Scoring;
|
||||
/// </summary>
|
||||
internal class Penalty3 : Penalty
|
||||
{
|
||||
/// <summary>
|
||||
/// Calculate penalty value for Third rule.
|
||||
/// </summary>
|
||||
internal override int PenaltyCalculate(BitMatrix matrix) => PenaltyCalculation(matrix, true) + PenaltyCalculation(matrix, false);
|
||||
/// <summary>
|
||||
/// Calculate penalty value for Third rule.
|
||||
/// </summary>
|
||||
internal override int PenaltyCalculate(BitMatrix matrix) => PenaltyCalculation(matrix, true) + PenaltyCalculation(matrix, false);
|
||||
|
||||
private int PenaltyCalculation(BitMatrix matrix, bool isHorizontal)
|
||||
{
|
||||
int i = 0;
|
||||
int j = 1;
|
||||
int penalty = 0;
|
||||
int width = matrix.Width;
|
||||
bool bit;
|
||||
while (i < width)
|
||||
{
|
||||
while (j < width - 5)
|
||||
{
|
||||
bit = isHorizontal
|
||||
? matrix[j + 4, i]
|
||||
: matrix[i, j + 4];
|
||||
if (!bit)
|
||||
{
|
||||
bit = isHorizontal
|
||||
? matrix[j, i]
|
||||
: matrix[i, j];
|
||||
if (!bit)
|
||||
{
|
||||
penalty += PatternCheck(matrix, i, j, isHorizontal);
|
||||
j += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
j += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int num = 4; num > 0; num--)
|
||||
{
|
||||
bit = isHorizontal
|
||||
? matrix[j + num, i]
|
||||
: matrix[i, j + num];
|
||||
if (!bit)
|
||||
{
|
||||
j += num;
|
||||
break;
|
||||
}
|
||||
if (num == 1)
|
||||
{
|
||||
j += 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
j = 0;
|
||||
i++;
|
||||
}
|
||||
return penalty;
|
||||
}
|
||||
private int PenaltyCalculation(BitMatrix matrix, bool isHorizontal)
|
||||
{
|
||||
int i = 0;
|
||||
int j = 1;
|
||||
int penalty = 0;
|
||||
int width = matrix.Width;
|
||||
bool bit;
|
||||
while (i < width)
|
||||
{
|
||||
while (j < width - 5)
|
||||
{
|
||||
bit = isHorizontal
|
||||
? matrix[j + 4, i]
|
||||
: matrix[i, j + 4];
|
||||
if (!bit)
|
||||
{
|
||||
bit = isHorizontal
|
||||
? matrix[j, i]
|
||||
: matrix[i, j];
|
||||
if (!bit)
|
||||
{
|
||||
penalty += PatternCheck(matrix, i, j, isHorizontal);
|
||||
j += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
j += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int num = 4; num > 0; num--)
|
||||
{
|
||||
bit = isHorizontal
|
||||
? matrix[j + num, i]
|
||||
: matrix[i, j + num];
|
||||
if (!bit)
|
||||
{
|
||||
j += num;
|
||||
break;
|
||||
}
|
||||
if (num == 1)
|
||||
{
|
||||
j += 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
j = 0;
|
||||
i++;
|
||||
}
|
||||
return penalty;
|
||||
}
|
||||
|
||||
private int PatternCheck(BitMatrix matrix, int i, int j, bool isHorizontal)
|
||||
{
|
||||
bool bit;
|
||||
for (int num = 3; num >= 1; num--)
|
||||
{
|
||||
bit = isHorizontal
|
||||
? matrix[j + num, i]
|
||||
: matrix[i, j + num];
|
||||
if (!bit)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
private int PatternCheck(BitMatrix matrix, int i, int j, bool isHorizontal)
|
||||
{
|
||||
bool bit;
|
||||
for (int num = 3; num >= 1; num--)
|
||||
{
|
||||
bit = isHorizontal
|
||||
? matrix[j + num, i]
|
||||
: matrix[i, j + num];
|
||||
if (!bit)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for left side and right side x ( xoxxxox ).
|
||||
if ((j - 1) < 0 || (j + 1) >= matrix.Width)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// Check for left side and right side x ( xoxxxox ).
|
||||
if ((j - 1) < 0 || (j + 1) >= matrix.Width)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bit = isHorizontal
|
||||
? matrix[j + 5, i]
|
||||
: matrix[i, j + 5];
|
||||
if (!bit)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
bit = isHorizontal
|
||||
? matrix[j + 5, i]
|
||||
: matrix[i, j + 5];
|
||||
if (!bit)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bit = isHorizontal
|
||||
? matrix[j - 1, i]
|
||||
: matrix[i, j - 1];
|
||||
if (!bit)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
bit = isHorizontal
|
||||
? matrix[j - 1, i]
|
||||
: matrix[i, j - 1];
|
||||
if (!bit)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((j - 5) >= 0)
|
||||
{
|
||||
for (int num = -2; num >= -5; num--)
|
||||
{
|
||||
bit = isHorizontal
|
||||
? matrix[j + num, i]
|
||||
: matrix[i, j + num];
|
||||
if (bit)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if ((j - 5) >= 0)
|
||||
{
|
||||
for (int num = -2; num >= -5; num--)
|
||||
{
|
||||
bit = isHorizontal
|
||||
? matrix[j + num, i]
|
||||
: matrix[i, j + num];
|
||||
if (bit)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (num == -5)
|
||||
{
|
||||
return 40;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (num == -5)
|
||||
{
|
||||
return 40;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((j + 9) < matrix.Width)
|
||||
{
|
||||
for (int num = 6; num <= 9; num++)
|
||||
{
|
||||
bit = isHorizontal
|
||||
? matrix[j + num, i]
|
||||
: matrix[i, j + num];
|
||||
if (bit)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 40;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((j + 9) < matrix.Width)
|
||||
{
|
||||
for (int num = 6; num <= 9; num++)
|
||||
{
|
||||
bit = isHorizontal
|
||||
? matrix[j + num, i]
|
||||
: matrix[i, j + num];
|
||||
if (bit)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 40;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
using System;
|
||||
|
||||
namespace Gma.QrCodeNet.Encoding.Masking.Scoring;
|
||||
|
||||
/// <summary>
|
||||
@@ -7,30 +5,30 @@ namespace Gma.QrCodeNet.Encoding.Masking.Scoring;
|
||||
/// </summary>
|
||||
internal class Penalty4 : Penalty
|
||||
{
|
||||
/// <summary>
|
||||
/// Calculate penalty value for Fourth rule.
|
||||
/// Perform O(n) search for available x modules
|
||||
/// </summary>
|
||||
internal override int PenaltyCalculate(BitMatrix matrix)
|
||||
{
|
||||
int width = matrix.Width;
|
||||
int darkBitCount = 0;
|
||||
/// <summary>
|
||||
/// Calculate penalty value for Fourth rule.
|
||||
/// Perform O(n) search for available x modules
|
||||
/// </summary>
|
||||
internal override int PenaltyCalculate(BitMatrix matrix)
|
||||
{
|
||||
int width = matrix.Width;
|
||||
int darkBitCount = 0;
|
||||
|
||||
for (int j = 0; j < width; j++)
|
||||
{
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
if (matrix[i, j])
|
||||
{
|
||||
darkBitCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < width; j++)
|
||||
{
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
if (matrix[i, j])
|
||||
{
|
||||
darkBitCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int matrixCount = width * width;
|
||||
int matrixCount = width * width;
|
||||
|
||||
double ratio = (double)darkBitCount / matrixCount;
|
||||
double ratio = (double)darkBitCount / matrixCount;
|
||||
|
||||
return Math.Abs((int)((ratio * 100) - 50)) / 5 * 10;
|
||||
}
|
||||
}
|
||||
return Math.Abs((int)((ratio * 100) - 50)) / 5 * 10;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,3 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Gma.QrCodeNet.Encoding.Masking.Scoring;
|
||||
|
||||
/// <summary>
|
||||
@@ -8,23 +5,23 @@ namespace Gma.QrCodeNet.Encoding.Masking.Scoring;
|
||||
/// </summary>
|
||||
internal class PenaltyFactory
|
||||
{
|
||||
internal Penalty CreateByRule(PenaltyRules penaltyRule)
|
||||
{
|
||||
return penaltyRule switch
|
||||
{
|
||||
PenaltyRules.Rule01 => new Penalty1(),
|
||||
PenaltyRules.Rule02 => new Penalty2(),
|
||||
PenaltyRules.Rule03 => new Penalty3(),
|
||||
PenaltyRules.Rule04 => new Penalty4(),
|
||||
_ => throw new ArgumentException($"Unsupport penalty rule: {penaltyRule}", nameof(penaltyRule))
|
||||
};
|
||||
}
|
||||
internal Penalty CreateByRule(PenaltyRules penaltyRule)
|
||||
{
|
||||
return penaltyRule switch
|
||||
{
|
||||
PenaltyRules.Rule01 => new Penalty1(),
|
||||
PenaltyRules.Rule02 => new Penalty2(),
|
||||
PenaltyRules.Rule03 => new Penalty3(),
|
||||
PenaltyRules.Rule04 => new Penalty4(),
|
||||
_ => throw new ArgumentException($"Unsupport penalty rule: {penaltyRule}", nameof(penaltyRule))
|
||||
};
|
||||
}
|
||||
|
||||
internal IEnumerable<Penalty> AllRules()
|
||||
{
|
||||
foreach (PenaltyRules penaltyRule in Enum.GetValues(typeof(PenaltyRules)))
|
||||
{
|
||||
yield return CreateByRule(penaltyRule);
|
||||
}
|
||||
}
|
||||
}
|
||||
internal IEnumerable<Penalty> AllRules()
|
||||
{
|
||||
foreach (PenaltyRules penaltyRule in Enum.GetValues(typeof(PenaltyRules)))
|
||||
{
|
||||
yield return CreateByRule(penaltyRule);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,8 @@ namespace Gma.QrCodeNet.Encoding.Masking.Scoring;
|
||||
|
||||
public enum PenaltyRules
|
||||
{
|
||||
Rule01 = 1,
|
||||
Rule02 = 2,
|
||||
Rule03 = 3,
|
||||
Rule04 = 4
|
||||
}
|
||||
Rule01 = 1,
|
||||
Rule02 = 2,
|
||||
Rule03 = 3,
|
||||
Rule04 = 4
|
||||
}
|
||||
Reference in New Issue
Block a user