142 lines
2.2 KiB
C#
142 lines
2.2 KiB
C#
namespace Gma.QrCodeNet.Encoding.Masking.Scoring;
|
|
|
|
/// <summary>
|
|
/// ISO/IEC 18004:2000 Chapter 8.8.2 Page 52
|
|
/// </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);
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
// 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 - 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 (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;
|
|
}
|
|
}
|
|
}
|