Skip to content

Commit

Permalink
Merge pull request #516 from Shane32/code_separation
Browse files Browse the repository at this point in the history
Refactor QRCodeGenerator into separate files
  • Loading branch information
codebude authored May 5, 2024
2 parents e36d34d + 307e6aa commit e7a7eb2
Show file tree
Hide file tree
Showing 15 changed files with 735 additions and 646 deletions.
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

0 comments on commit e7a7eb2

Please sign in to comment.