Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor QRCodeGenerator into separate files #516

Merged
merged 3 commits into from
May 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions QRCoder/QRCodeGenerator.AlignmentPattern.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Collections.Generic;

namespace QRCoder
{
public partial class QRCodeGenerator
{
private struct AlignmentPattern
{
public int Version;
public List<Point> PatternPositions;
}
}
}
17 changes: 17 additions & 0 deletions QRCoder/QRCodeGenerator.CodewordBlock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace QRCoder
{
public partial class QRCodeGenerator
{
private struct CodewordBlock
{
public CodewordBlock(byte[] codeWords, byte[] eccWords)
{
this.CodeWords = codeWords;
this.ECCWords = eccWords;
}

public byte[] CodeWords { get; }
public byte[] ECCWords { get; }
}
}
}
29 changes: 29 additions & 0 deletions QRCoder/QRCodeGenerator.ECCInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace QRCoder
{
public partial class QRCodeGenerator
{
private struct ECCInfo
{
public ECCInfo(int version, ECCLevel errorCorrectionLevel, int totalDataCodewords, int eccPerBlock, int blocksInGroup1,
int codewordsInGroup1, int blocksInGroup2, int codewordsInGroup2)
{
this.Version = version;
this.ErrorCorrectionLevel = errorCorrectionLevel;
this.TotalDataCodewords = totalDataCodewords;
this.ECCPerBlock = eccPerBlock;
this.BlocksInGroup1 = blocksInGroup1;
this.CodewordsInGroup1 = codewordsInGroup1;
this.BlocksInGroup2 = blocksInGroup2;
this.CodewordsInGroup2 = codewordsInGroup2;
}
public int Version { get; }
public ECCLevel ErrorCorrectionLevel { get; }
public int TotalDataCodewords { get; }
public int ECCPerBlock { get; }
public int BlocksInGroup1 { get; }
public int CodewordsInGroup1 { get; }
public int BlocksInGroup2 { get; }
public int CodewordsInGroup2 { get; }
}
}
}
28 changes: 28 additions & 0 deletions QRCoder/QRCodeGenerator.ECCLevel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace QRCoder
{
public partial class QRCodeGenerator
{
/// <summary>
/// Error correction level. These define the tolerance levels for how much of the code can be lost before the code cannot be recovered.
/// </summary>
public enum ECCLevel
{
/// <summary>
/// 7% may be lost before recovery is not possible
/// </summary>
L,
/// <summary>
/// 15% may be lost before recovery is not possible
/// </summary>
M,
/// <summary>
/// 25% may be lost before recovery is not possible
/// </summary>
Q,
/// <summary>
/// 30% may be lost before recovery is not possible
/// </summary>
H
}
}
}
13 changes: 13 additions & 0 deletions QRCoder/QRCodeGenerator.EciMode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace QRCoder
{
public partial class QRCodeGenerator
{
public enum EciMode
{
Default = 0,
Iso8859_1 = 3,
Iso8859_2 = 4,
Utf8 = 26
}
}
}
14 changes: 14 additions & 0 deletions QRCoder/QRCodeGenerator.EncodingMode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace QRCoder
{
public partial class QRCodeGenerator
{
private enum EncodingMode
{
Numeric = 1,
Alphanumeric = 2,
Byte = 4,
Kanji = 8,
ECI = 7
}
}
}
187 changes: 187 additions & 0 deletions QRCoder/QRCodeGenerator.ModulePlacer.MaskPattern.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
using System;
using System.Collections.Generic;

namespace QRCoder
{
public partial class QRCodeGenerator
{
private static partial class ModulePlacer
{
private static class MaskPattern
{
public static readonly Dictionary<int, Func<int, int, bool>> Patterns =
new Dictionary<int, Func<int, int, bool>>(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 bool Pattern1(int x, int y)
{
return (x + y) % 2 == 0;
}

public static bool Pattern2(int x, int y)
{
return y % 2 == 0;
}

public static bool Pattern3(int x, int y)
{
return x % 3 == 0;
}

public static bool Pattern4(int x, int y)
{
return (x + y) % 3 == 0;
}

public static bool Pattern5(int x, int y)
{
return ((int)(Math.Floor(y / 2d) + Math.Floor(x / 3d)) % 2) == 0;
}

public static bool Pattern6(int x, int y)
{
return ((x * y) % 2) + ((x * y) % 3) == 0;
}

public static bool Pattern7(int x, int y)
{
return (((x * y) % 2) + ((x * y) % 3)) % 2 == 0;
}

public static bool Pattern8(int x, int y)
{
return (((x + y) % 2) + ((x * y) % 3)) % 2 == 0;
}

public static int Score(QRCodeData qrCode)
{
int score1 = 0,
score2 = 0,
score3 = 0,
score4 = 0;
var size = qrCode.ModuleMatrix.Count;

//Penalty 1
for (var y = 0; y < size; y++)
{
var modInRow = 0;
var modInColumn = 0;
var lastValRow = qrCode.ModuleMatrix[y][0];
var lastValColumn = qrCode.ModuleMatrix[0][y];
for (var x = 0; x < size; x++)
{
if (qrCode.ModuleMatrix[y][x] == lastValRow)
modInRow++;
else
modInRow = 1;
if (modInRow == 5)
score1 += 3;
else if (modInRow > 5)
score1++;
lastValRow = qrCode.ModuleMatrix[y][x];


if (qrCode.ModuleMatrix[x][y] == lastValColumn)
modInColumn++;
else
modInColumn = 1;
if (modInColumn == 5)
score1 += 3;
else if (modInColumn > 5)
score1++;
lastValColumn = qrCode.ModuleMatrix[x][y];
}
}


//Penalty 2
for (var y = 0; y < size - 1; y++)
{
for (var x = 0; x < size - 1; x++)
{
if (qrCode.ModuleMatrix[y][x] == qrCode.ModuleMatrix[y][x + 1] &&
qrCode.ModuleMatrix[y][x] == qrCode.ModuleMatrix[y + 1][x] &&
qrCode.ModuleMatrix[y][x] == qrCode.ModuleMatrix[y + 1][x + 1])
score2 += 3;
}
}

//Penalty 3
for (var y = 0; y < size; y++)
{
for (var x = 0; x < size - 10; x++)
{
if ((qrCode.ModuleMatrix[y][x] &&
!qrCode.ModuleMatrix[y][x + 1] &&
qrCode.ModuleMatrix[y][x + 2] &&
qrCode.ModuleMatrix[y][x + 3] &&
qrCode.ModuleMatrix[y][x + 4] &&
!qrCode.ModuleMatrix[y][x + 5] &&
qrCode.ModuleMatrix[y][x + 6] &&
!qrCode.ModuleMatrix[y][x + 7] &&
!qrCode.ModuleMatrix[y][x + 8] &&
!qrCode.ModuleMatrix[y][x + 9] &&
!qrCode.ModuleMatrix[y][x + 10]) ||
(!qrCode.ModuleMatrix[y][x] &&
!qrCode.ModuleMatrix[y][x + 1] &&
!qrCode.ModuleMatrix[y][x + 2] &&
!qrCode.ModuleMatrix[y][x + 3] &&
qrCode.ModuleMatrix[y][x + 4] &&
!qrCode.ModuleMatrix[y][x + 5] &&
qrCode.ModuleMatrix[y][x + 6] &&
qrCode.ModuleMatrix[y][x + 7] &&
qrCode.ModuleMatrix[y][x + 8] &&
!qrCode.ModuleMatrix[y][x + 9] &&
qrCode.ModuleMatrix[y][x + 10]))
{
score3 += 40;
}

if ((qrCode.ModuleMatrix[x][y] &&
!qrCode.ModuleMatrix[x + 1][y] &&
qrCode.ModuleMatrix[x + 2][y] &&
qrCode.ModuleMatrix[x + 3][y] &&
qrCode.ModuleMatrix[x + 4][y] &&
!qrCode.ModuleMatrix[x + 5][y] &&
qrCode.ModuleMatrix[x + 6][y] &&
!qrCode.ModuleMatrix[x + 7][y] &&
!qrCode.ModuleMatrix[x + 8][y] &&
!qrCode.ModuleMatrix[x + 9][y] &&
!qrCode.ModuleMatrix[x + 10][y]) ||
(!qrCode.ModuleMatrix[x][y] &&
!qrCode.ModuleMatrix[x + 1][y] &&
!qrCode.ModuleMatrix[x + 2][y] &&
!qrCode.ModuleMatrix[x + 3][y] &&
qrCode.ModuleMatrix[x + 4][y] &&
!qrCode.ModuleMatrix[x + 5][y] &&
qrCode.ModuleMatrix[x + 6][y] &&
qrCode.ModuleMatrix[x + 7][y] &&
qrCode.ModuleMatrix[x + 8][y] &&
!qrCode.ModuleMatrix[x + 9][y] &&
qrCode.ModuleMatrix[x + 10][y]))
{
score3 += 40;
}
}
}

//Penalty 4
int blackModules = 0;
foreach (var bitArray in qrCode.ModuleMatrix)
for (var x = 0; x < size; x++)
if (bitArray[x])
blackModules++;

var percentDiv5 = blackModules * 20 / (qrCode.ModuleMatrix.Count * qrCode.ModuleMatrix.Count);
var prevMultipleOf5 = Math.Abs(percentDiv5 - 10);
var nextMultipleOf5 = Math.Abs(percentDiv5 - 9);
score4 = Math.Min(prevMultipleOf5, nextMultipleOf5) * 10;

return (score1 + score2) + (score3 + score4);
}
}
}
}
}
Loading